@firecms/core 3.0.1 → 3.1.0-canary.24c8270

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 (186) 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/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
  10. package/dist/components/EntityCollectionView/Board.d.ts +2 -0
  11. package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
  12. package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
  13. package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
  14. package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
  15. package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
  16. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
  17. package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
  18. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
  19. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +7 -3
  20. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
  21. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +44 -0
  22. package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
  23. package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
  24. package/dist/components/ErrorBoundary.d.ts +1 -1
  25. package/dist/components/SelectableTable/SelectableTable.d.ts +5 -1
  26. package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
  27. package/dist/components/VirtualTable/VirtualTableCell.d.ts +6 -0
  28. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +3 -1
  29. package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
  30. package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -0
  31. package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +1 -0
  32. package/dist/components/VirtualTable/types.d.ts +2 -0
  33. package/dist/components/index.d.ts +3 -0
  34. package/dist/contexts/index.d.ts +10 -0
  35. package/dist/core/DrawerNavigationGroup.d.ts +45 -0
  36. package/dist/core/index.d.ts +1 -0
  37. package/dist/form/components/ErrorFocus.d.ts +1 -1
  38. package/dist/form/validation.d.ts +3 -2
  39. package/dist/hooks/useBreadcrumbsController.d.ts +16 -0
  40. package/dist/hooks/useCollapsedGroups.d.ts +4 -1
  41. package/dist/index.es.js +5316 -1592
  42. package/dist/index.es.js.map +1 -1
  43. package/dist/index.umd.js +5309 -1586
  44. package/dist/index.umd.js.map +1 -1
  45. package/dist/internal/useRestoreScroll.d.ts +1 -1
  46. package/dist/preview/PropertyPreviewProps.d.ts +5 -0
  47. package/dist/preview/components/DatePreview.d.ts +13 -3
  48. package/dist/preview/components/ImagePreview.d.ts +5 -1
  49. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  50. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  51. package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
  52. package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
  53. package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
  54. package/dist/types/analytics.d.ts +1 -1
  55. package/dist/types/collections.d.ts +50 -2
  56. package/dist/types/datasource.d.ts +0 -1
  57. package/dist/types/plugins.d.ts +62 -1
  58. package/dist/types/properties.d.ts +259 -4
  59. package/dist/util/__tests__/conditions.test.d.ts +1 -0
  60. package/dist/util/__tests__/objects.test.d.ts +1 -0
  61. package/dist/util/conditions.d.ts +26 -0
  62. package/dist/util/entities.d.ts +2 -3
  63. package/dist/util/index.d.ts +2 -1
  64. package/dist/util/property_utils.d.ts +2 -1
  65. package/dist/util/resolutions.d.ts +3 -3
  66. package/package.json +14 -11
  67. package/src/app/Scaffold.tsx +14 -15
  68. package/src/components/AIIcon.tsx +39 -0
  69. package/src/components/ArrayContainer.tsx +1 -4
  70. package/src/components/ClearFilterSortButton.tsx +19 -16
  71. package/src/components/ConfirmationDialog.tsx +0 -2
  72. package/src/components/DeleteEntityDialog.tsx +2 -4
  73. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +74 -41
  74. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +130 -79
  75. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +121 -104
  76. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +132 -103
  77. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +20 -42
  78. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +90 -49
  79. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  80. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  81. package/src/components/EntityCollectionView/Board.tsx +324 -0
  82. package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
  83. package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
  84. package/src/components/EntityCollectionView/BoardSortableList.tsx +172 -0
  85. package/src/components/EntityCollectionView/EntityBoardCard.tsx +212 -0
  86. package/src/components/EntityCollectionView/EntityCard.tsx +235 -0
  87. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +733 -0
  88. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +244 -0
  89. package/src/components/EntityCollectionView/EntityCollectionView.tsx +519 -203
  90. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +31 -19
  91. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +84 -15
  92. package/src/components/EntityCollectionView/FiltersDialog.tsx +249 -0
  93. package/src/components/EntityCollectionView/ViewModeToggle.tsx +199 -0
  94. package/src/components/EntityCollectionView/board_types.ts +113 -0
  95. package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
  96. package/src/components/ErrorTooltip.tsx +2 -1
  97. package/src/components/HomePage/DefaultHomePage.tsx +47 -10
  98. package/src/components/HomePage/HomePageDnD.tsx +56 -41
  99. package/src/components/HomePage/NavigationCard.tsx +20 -18
  100. package/src/components/HomePage/NavigationGroup.tsx +17 -16
  101. package/src/components/HomePage/RenameGroupDialog.tsx +0 -2
  102. package/src/components/HomePage/SmallNavigationCard.tsx +10 -9
  103. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -10
  104. package/src/components/ReferenceWidget.tsx +2 -4
  105. package/src/components/SelectableTable/SelectableTable.tsx +75 -67
  106. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +7 -6
  107. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +39 -40
  108. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -38
  109. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +49 -58
  110. package/src/components/UnsavedChangesDialog.tsx +0 -2
  111. package/src/components/UserDisplay.tsx +4 -4
  112. package/src/components/VirtualTable/VirtualTable.tsx +272 -118
  113. package/src/components/VirtualTable/VirtualTableCell.tsx +18 -2
  114. package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -50
  115. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +158 -42
  116. package/src/components/VirtualTable/VirtualTableProps.tsx +14 -1
  117. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  118. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -0
  119. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +19 -6
  120. package/src/components/VirtualTable/types.tsx +2 -0
  121. package/src/components/common/useColumnsIds.tsx +95 -3
  122. package/src/components/common/useDataSourceTableController.tsx +21 -4
  123. package/src/components/index.tsx +4 -0
  124. package/src/contexts/BreacrumbsContext.tsx +15 -8
  125. package/src/contexts/index.ts +10 -0
  126. package/src/core/DefaultAppBar.tsx +40 -27
  127. package/src/core/DefaultDrawer.tsx +42 -56
  128. package/src/core/DrawerNavigationGroup.tsx +118 -0
  129. package/src/core/DrawerNavigationItem.tsx +4 -3
  130. package/src/core/EntityEditView.tsx +41 -43
  131. package/src/core/EntitySidePanel.tsx +28 -26
  132. package/src/core/SideDialogs.tsx +4 -2
  133. package/src/core/field_configs.tsx +14 -9
  134. package/src/core/index.tsx +1 -0
  135. package/src/form/EntityForm.tsx +69 -60
  136. package/src/form/PropertyFieldBinding.tsx +61 -46
  137. package/src/form/components/ErrorFocus.tsx +3 -3
  138. package/src/form/components/StorageItemPreview.tsx +2 -1
  139. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -1
  140. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -16
  141. package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -1
  142. package/src/form/field_bindings/MapFieldBinding.tsx +69 -67
  143. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +22 -18
  144. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +83 -83
  145. package/src/form/field_bindings/TextFieldBinding.tsx +71 -35
  146. package/src/form/validation.ts +245 -160
  147. package/src/hooks/useBreadcrumbsController.tsx +18 -0
  148. package/src/hooks/useBuildNavigationController.tsx +71 -28
  149. package/src/hooks/useCollapsedGroups.ts +12 -4
  150. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  151. package/src/internal/useBuildDataSource.ts +68 -34
  152. package/src/internal/useBuildSideDialogsController.tsx +11 -8
  153. package/src/internal/useBuildSideEntityController.tsx +24 -24
  154. package/src/internal/useRestoreScroll.tsx +26 -14
  155. package/src/preview/PropertyPreview.tsx +41 -32
  156. package/src/preview/PropertyPreviewProps.tsx +6 -0
  157. package/src/preview/components/DatePreview.tsx +72 -4
  158. package/src/preview/components/EmptyValue.tsx +1 -1
  159. package/src/preview/components/ImagePreview.tsx +37 -21
  160. package/src/preview/components/StorageThumbnail.tsx +16 -12
  161. package/src/preview/components/UrlComponentPreview.tsx +28 -25
  162. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
  163. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
  164. package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
  165. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
  166. package/src/routes/CustomCMSRoute.tsx +1 -0
  167. package/src/routes/FireCMSRoute.tsx +26 -13
  168. package/src/types/analytics.ts +10 -0
  169. package/src/types/collections.ts +57 -3
  170. package/src/types/datasource.ts +54 -56
  171. package/src/types/plugins.tsx +69 -1
  172. package/src/types/properties.ts +347 -27
  173. package/src/util/__tests__/conditions.test.ts +506 -0
  174. package/src/util/__tests__/objects.test.ts +196 -0
  175. package/src/util/callbacks.ts +6 -3
  176. package/src/util/collections.ts +51 -6
  177. package/src/util/conditions.ts +339 -0
  178. package/src/util/entities.ts +29 -30
  179. package/src/util/entity_cache.ts +2 -1
  180. package/src/util/index.ts +2 -1
  181. package/src/util/join_collections.ts +10 -8
  182. package/src/util/objects.ts +31 -13
  183. package/src/util/{references.ts → previews.ts} +16 -2
  184. package/src/util/property_utils.tsx +37 -11
  185. package/src/util/resolutions.ts +62 -58
  186. /package/dist/util/{references.d.ts → previews.d.ts} +0 -0
@@ -15,7 +15,8 @@ export declare function getPropertyInPath<M extends Record<string, any>>(propert
15
15
  export declare function getResolvedPropertyInPath(properties: Record<string, ResolvedProperty>, path: string): ResolvedProperty | undefined;
16
16
  export declare function getBracketNotation(path: string): string;
17
17
  /**
18
- * Get properties exclusively indexed by their order
18
+ * Get properties sorted by their order, but include ALL properties.
19
+ * Nested keys (like "data.mode") in propertiesOrder are ignored - they're for column ordering.
19
20
  * @param properties
20
21
  * @param propertiesOrder
21
22
  */
@@ -1,4 +1,4 @@
1
- import { ArrayProperty, AuthController, CMSType, CustomizationController, EntityAction, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
1
+ import { ArrayProperty, AuthController, CMSType, CustomizationController, EntityAction, EntityCollection, EntityCustomView, EntityValues, EnumValueConfig, EnumValues, NumberProperty, PropertiesOrBuilders, Property, PropertyConfig, PropertyOrBuilder, ResolvedArrayProperty, ResolvedEntityCollection, ResolvedNumberProperty, ResolvedProperties, ResolvedProperty, ResolvedStringProperty, StringProperty, UserConfigurationPersistence } from "../types";
2
2
  export declare const resolveCollection: <M extends Record<string, any>>({ collection, path, entityId, values, previousValues, userConfigPersistence, propertyConfigs, ignoreMissingFields, authController }: {
3
3
  collection: EntityCollection<M> | ResolvedEntityCollection<M>;
4
4
  path: string;
@@ -17,7 +17,7 @@ export declare const resolveCollection: <M extends Record<string, any>>({ collec
17
17
  */
18
18
  export declare function resolveProperty<T extends CMSType = CMSType, M extends Record<string, any> = any>({ propertyOrBuilder, fromBuilder, ignoreMissingFields, ...props }: {
19
19
  propertyKey?: string;
20
- propertyOrBuilder: PropertyOrBuilder<T, M> | ResolvedProperty<T>;
20
+ propertyOrBuilder: PropertyOrBuilder<T, M> | ResolvedProperty<T> | PropertyOrBuilder | Property | ResolvedProperty | undefined;
21
21
  values?: Partial<M>;
22
22
  previousValues?: Partial<M>;
23
23
  path?: string;
@@ -54,7 +54,7 @@ export declare function resolveArrayProperty<T extends any[], M>({ propertyKey,
54
54
  propertyConfigs?: Record<string, PropertyConfig>;
55
55
  ignoreMissingFields?: boolean;
56
56
  authController: AuthController;
57
- }): ResolvedArrayProperty;
57
+ }): ResolvedArrayProperty | null;
58
58
  /**
59
59
  * Resolve enums and arrays for properties
60
60
  * @param properties
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.1",
4
+ "version": "3.1.0-canary.24c8270",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -53,15 +53,16 @@
53
53
  "@dnd-kit/core": "^6.3.1",
54
54
  "@dnd-kit/modifiers": "^9.0.0",
55
55
  "@dnd-kit/sortable": "^10.0.0",
56
- "@firecms/editor": "^3.0.1",
57
- "@firecms/formex": "^3.0.1",
58
- "@firecms/ui": "^3.0.1",
56
+ "@firecms/editor": "^3.1.0-canary.24c8270",
57
+ "@firecms/formex": "^3.1.0-canary.24c8270",
58
+ "@firecms/ui": "^3.1.0-canary.24c8270",
59
59
  "@radix-ui/react-portal": "^1.1.10",
60
60
  "clsx": "^2.1.1",
61
61
  "compressorjs": "^1.2.1",
62
62
  "date-fns": "^3.6.0",
63
63
  "fuse.js": "^7.1.0",
64
64
  "history": "^5.3.0",
65
+ "json-logic-js": "^2.0.5",
65
66
  "markdown-it": "^14.1.0",
66
67
  "notistack": "^3.0.2",
67
68
  "object-hash": "^3.0.0",
@@ -72,11 +73,11 @@
72
73
  "react-use-measure": "^2.1.7",
73
74
  "react-window": "^1.8.11",
74
75
  "vite-plugin-static-copy": "3.1.4",
75
- "yup": "^0.32.11"
76
+ "yup": "^1.7.1"
76
77
  },
77
78
  "peerDependencies": {
78
- "react": ">=18.0.0",
79
- "react-dom": ">=18.0.0",
79
+ "react": ">=18.3.1 || >=19.0.0",
80
+ "react-dom": ">=18.3.1 || >=19.0.0",
80
81
  "react-router": "^6.28.0",
81
82
  "react-router-dom": "^6.28.0"
82
83
  },
@@ -85,10 +86,11 @@
85
86
  "@testing-library/react": "^16.3.0",
86
87
  "@testing-library/user-event": "^14.6.1",
87
88
  "@types/jest": "^29.5.14",
89
+ "@types/json-logic-js": "^2.0.8",
88
90
  "@types/node": "^20.19.17",
89
91
  "@types/object-hash": "^3.0.6",
90
- "@types/react": "^18.3.24",
91
- "@types/react-dom": "^18.3.7",
92
+ "@types/react": "^19.2.3",
93
+ "@types/react-dom": "^19.2.3",
92
94
  "@types/react-measure": "^2.0.12",
93
95
  "@vitejs/plugin-react": "^4.7.0",
94
96
  "babel-plugin-react-compiler": "^19.0.0-beta-af1b7da-20250417",
@@ -109,7 +111,7 @@
109
111
  "dist",
110
112
  "src"
111
113
  ],
112
- "gitHead": "72d951d01d15ef5a7efcde6c63839f65964d2f7a",
114
+ "gitHead": "fa98925bad34308ed66e7ea68adcc07eb38184ae",
113
115
  "publishConfig": {
114
116
  "access": "public"
115
117
  },
@@ -134,7 +136,8 @@
134
136
  ],
135
137
  "testEnvironment": "node",
136
138
  "moduleNameMapper": {
137
- "\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js"
139
+ "\\.(css|less)$": "<rootDir>/test/__mocks__/styleMock.js",
140
+ "^@firecms/editor$": "<rootDir>/test/__mocks__/editorMock.js"
138
141
  }
139
142
  }
140
143
  }
@@ -123,7 +123,7 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
123
123
  <main
124
124
  className="flex flex-col flex-grow overflow-auto">
125
125
 
126
- {hasAppBar && <DrawerHeader/>}
126
+ {hasAppBar && <DrawerHeader />}
127
127
 
128
128
  <div
129
129
  className={cls(defaultBorderMixin, "flex-grow overflow-auto m-0 ", {
@@ -174,9 +174,9 @@ function DrawerWrapper(props: {
174
174
 
175
175
  {!props.open && props.displayed && (
176
176
  <Tooltip title="Open menu"
177
- side="right"
178
- sideOffset={12}
179
- asChild={true}>
177
+ side="right"
178
+ sideOffset={12}
179
+ asChild={true}>
180
180
  <div
181
181
  className="ml-2 fixed top-1 left-2 sm:top-2 sm:left-2 !bg-surface-50 dark:!bg-surface-900 rounded-full w-fit z-20">
182
182
  <IconButton
@@ -185,21 +185,20 @@ function DrawerWrapper(props: {
185
185
  onClick={() => props.setDrawerOpen(true)}
186
186
  size="large"
187
187
  >
188
- <MenuIcon/>
188
+ <MenuIcon size="small" />
189
189
  </IconButton>
190
190
  </div>
191
191
  </Tooltip>
192
192
  )}
193
193
 
194
194
  <div
195
- className={`z-20 absolute right-0 top-4 ${
196
- props.open ? "opacity-100" : "opacity-0 invisible"
197
- } transition-opacity duration-200 ease-in-out`}>
195
+ className={`z-20 absolute right-0 top-4 ${props.open ? "opacity-100" : "opacity-0 invisible"
196
+ } transition-opacity duration-200 ease-in-out`}>
198
197
  <IconButton
199
198
  aria-label="Close drawer"
200
199
  onClick={() => props.setDrawerOpen(false)}
201
200
  >
202
- <ChevronLeftIcon/>
201
+ <ChevronLeftIcon />
203
202
  </IconButton>
204
203
  </div>
205
204
 
@@ -221,14 +220,14 @@ function DrawerWrapper(props: {
221
220
  size="large"
222
221
  className="absolute sm:top-2 sm:left-4 top-1 left-2"
223
222
  >
224
- <MenuIcon/>
223
+ <MenuIcon />
225
224
  </IconButton>
226
225
  <Sheet side={"left"}
227
- transparent={true}
228
- open={props.open}
229
- onOpenChange={props.setDrawerOpen}
230
- title={"Navigation drawer"}
231
- overlayClassName={"bg-white bg-opacity-80"}
226
+ transparent={true}
227
+ open={props.open}
228
+ onOpenChange={props.setDrawerOpen}
229
+ title={"Navigation drawer"}
230
+ overlayClassName={"bg-white bg-opacity-80 bg-white/80"}
232
231
  >
233
232
  {innerDrawer}
234
233
  </Sheet>
@@ -0,0 +1,39 @@
1
+ import React from "react";
2
+ import { AutoAwesomeIcon } from "@firecms/ui";
3
+
4
+ export interface AIIconProps {
5
+ size?: "smallest" | "small" | "medium" | "large";
6
+ className?: string;
7
+ }
8
+
9
+ /**
10
+ * AI-styled AutoAwesome icon with gradient coloring.
11
+ * Used consistently across AI features for visual identification.
12
+ */
13
+ export function AIIcon({ size = "small", className }: AIIconProps) {
14
+ return (
15
+ <AutoAwesomeIcon
16
+ size={size}
17
+ className={className}
18
+ style={{
19
+ background: "linear-gradient(to right, var(--color-primary), var(--color-secondary))",
20
+ WebkitBackgroundClip: "text",
21
+ WebkitTextFillColor: "transparent",
22
+ backgroundClip: "text"
23
+ }}
24
+ />
25
+ );
26
+ }
27
+
28
+ /**
29
+ * Small animated dot indicator for AI-modified elements.
30
+ * Shows a pulsing gradient dot.
31
+ */
32
+ export function AIModifiedIndicator({ className }: { className?: string }) {
33
+ return (
34
+ <div
35
+ className={`w-2 h-2 rounded-full bg-gradient-to-r from-primary to-secondary animate-pulse ${className ?? ""}`}
36
+ title="AI modified"
37
+ />
38
+ );
39
+ }
@@ -186,7 +186,7 @@ export function ArrayContainerItem({
186
186
  <div
187
187
  ref={nodeRef}
188
188
  style={style}
189
- className={`relative ${!isDragging ? "hover\\:bg-surface-accent-50 dark\\:hover\\:bg-surface-800 dark\\:hover\\:bg-opacity-20" : ""} rounded-md opacity-100`}
189
+ className={`relative ${!isDragging ? "hover\\:bg-surface-accent-50 dark\\:hover\\:bg-surface-800 dark\\:hover\\:bg-opacity-20 dark\\:hover\\:bg-surface-800/20" : ""} rounded-md opacity-100`}
190
190
  >
191
191
  <div className="flex items-start">
192
192
  <div className="flex-grow w-[calc(100%-48px)] text-text-primary dark:text-text-primary-dark">
@@ -484,11 +484,9 @@ export function ArrayContainer<T>({
484
484
  <Button
485
485
  variant={"text"}
486
486
  size={size === "small" ? "small" : "medium"}
487
- color="primary"
488
487
  disabled={disabled || (value?.length ?? 0) >= max}
489
488
  startIcon={<AddIcon/>}
490
489
  onClick={insertInEnd}
491
- className={"ml-3.5"}
492
490
  >
493
491
  {addLabel ?? "Add"}
494
492
  </Button>
@@ -527,7 +525,6 @@ export function ArrayContainer<T>({
527
525
  <Button
528
526
  variant={"text"}
529
527
  size={size === "small" ? "small" : "medium"}
530
- color="primary"
531
528
  disabled={disabled || (value?.length ?? 0) >= max}
532
529
  startIcon={<AddIcon/>}
533
530
  onClick={insertInEnd}
@@ -1,10 +1,10 @@
1
- import { Button, FilterListOffIcon } from "@firecms/ui";
1
+ import { FilterListOffIcon, Button, Tooltip } from "@firecms/ui";
2
2
  import { EntityTableController } from "../types";
3
3
 
4
4
  export function ClearFilterSortButton({
5
- tableController,
6
- enabled
7
- }: {
5
+ tableController,
6
+ enabled
7
+ }: {
8
8
  enabled: boolean;
9
9
  tableController: EntityTableController
10
10
  }) {
@@ -24,18 +24,21 @@ export function ClearFilterSortButton({
24
24
  } else {
25
25
  label = "Clear sort";
26
26
  }
27
- return <Button
28
- variant={"outlined"}
29
- className="h-fit-content"
30
- aria-label="filter clear"
31
- onClick={() => {
32
- tableController.clearFilter?.();
33
- tableController.setSortBy?.(undefined);
34
- }}
35
- size={"small"}>
36
- <FilterListOffIcon/>
37
- {label}
38
- </Button>
27
+ return (
28
+ <Tooltip title={label}>
29
+ <Button
30
+ size={"small"}
31
+ variant={"text"}
32
+ aria-label={label}
33
+ onClick={() => {
34
+ tableController.clearFilter?.();
35
+ tableController.setSortBy?.(undefined);
36
+ }}
37
+ >
38
+ <FilterListOffIcon size="small" />
39
+ </Button>
40
+ </Tooltip>
41
+ );
39
42
  }
40
43
  return null;
41
44
  }
@@ -29,13 +29,11 @@ export function ConfirmationDialog({
29
29
 
30
30
  <DialogActions>
31
31
  <Button
32
- color={"primary"}
33
32
  variant={"text"}
34
33
  onClick={onCancel}
35
34
  autoFocus>Cancel</Button>
36
35
 
37
36
  <LoadingButton
38
- color="primary"
39
37
  type="submit"
40
38
  loading={loading}
41
39
  onClick={onAccept}
@@ -187,16 +187,14 @@ export function DeleteEntityDialog<M extends Record<string, any>>({
187
187
 
188
188
  <Button onClick={handleCancel}
189
189
  disabled={loading}
190
- variant="text"
191
- color="primary">
190
+ variant="text">
192
191
  Cancel
193
192
  </Button>
194
193
  <Button
195
194
  autoFocus
196
195
  disabled={loading}
197
196
  onClick={handleOk}
198
- variant="filled"
199
- color="primary">
197
+ variant="filled">
200
198
  Ok
201
199
  </Button>
202
200
  </DialogActions>
@@ -20,41 +20,52 @@ import { getLocalChangesBackup } from "../../util";
20
20
  * @group Collection components
21
21
  */
22
22
  export const EntityCollectionRowActions = function EntityCollectionRowActions({
23
- entity,
24
- collection,
25
- fullPath,
26
- fullIdPath,
27
- width,
28
- frozen,
29
- isSelected,
30
- selectionEnabled,
31
- size,
32
- highlightEntity,
33
- onCollectionChange,
34
- unhighlightEntity,
35
- actions = [],
36
- hideId,
37
- selectionController,
38
- openEntityMode
39
- }:
40
- {
41
- entity: Entity<any>,
42
- collection?: EntityCollection<any>,
43
- fullPath?: string,
44
- fullIdPath?: string,
45
- width: number,
46
- frozen?: boolean,
47
- size: CollectionSize,
48
- isSelected?: boolean,
49
- selectionEnabled?: boolean,
50
- actions?: EntityAction[],
51
- hideId?: boolean,
52
- onCollectionChange?: () => void,
53
- selectionController?: SelectionController;
54
- highlightEntity?: (entity: Entity<any>) => void;
55
- unhighlightEntity?: (entity: Entity<any>) => void;
56
- openEntityMode: "side_panel" | "full_screen";
57
- }) {
23
+ entity,
24
+ collection,
25
+ fullPath,
26
+ fullIdPath,
27
+ width,
28
+ frozen,
29
+ isSelected,
30
+ selectionEnabled,
31
+ size,
32
+ highlightEntity,
33
+ onCollectionChange,
34
+ unhighlightEntity,
35
+ actions = [],
36
+ hideId,
37
+ selectionController,
38
+ openEntityMode,
39
+ sortableNodeRef,
40
+ sortableStyle,
41
+ sortableAttributes,
42
+ isDragging,
43
+ isDraggable
44
+ }:
45
+ {
46
+ entity: Entity<any>,
47
+ collection?: EntityCollection<any>,
48
+ fullPath?: string,
49
+ fullIdPath?: string,
50
+ width: number,
51
+ frozen?: boolean,
52
+ size: CollectionSize,
53
+ isSelected?: boolean,
54
+ selectionEnabled?: boolean,
55
+ actions?: EntityAction[],
56
+ hideId?: boolean,
57
+ onCollectionChange?: () => void,
58
+ selectionController?: SelectionController;
59
+ highlightEntity?: (entity: Entity<any>) => void;
60
+ unhighlightEntity?: (entity: Entity<any>) => void;
61
+ openEntityMode: "side_panel" | "full_screen";
62
+ // Sortable props for dnd-kit integration
63
+ sortableNodeRef?: (node: HTMLElement | null) => void;
64
+ sortableStyle?: React.CSSProperties;
65
+ sortableAttributes?: Record<string, any>;
66
+ isDragging?: boolean;
67
+ isDraggable?: boolean;
68
+ }) {
58
69
 
59
70
  const largeLayout = useLargeLayout();
60
71
 
@@ -72,10 +83,11 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
72
83
  const enableLocalChangesBackup = collection ? getLocalChangesBackup(collection) : false;
73
84
  const hasDraft = enableLocalChangesBackup ? getEntityFromCache(fullPath + "/" + entity.id) : false;
74
85
  const iconSize = largeLayout && (size === "m" || size === "l" || size == "xl") ? "medium" : "small";
75
- return (
86
+
87
+ const content = (
76
88
  <div
77
89
  className={cls(
78
- "h-full flex items-center justify-center flex-col bg-surface-50 dark:bg-surface-900 bg-opacity-90 dark:bg-opacity-90 z-10",
90
+ "h-full flex items-center justify-center flex-col bg-surface-50 dark:bg-surface-900 bg-opacity-90 bg-surface-50/90 dark:bg-opacity-90 dark:bg-surface-900/90 z-10",
79
91
  frozen ? "sticky left-0" : ""
80
92
  )}
81
93
  onClick={useCallback((event: any) => {
@@ -124,8 +136,8 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
124
136
  }
125
137
  return (
126
138
  <Tooltip key={index}
127
- title={tooltip}
128
- asChild={true}>
139
+ title={tooltip}
140
+ asChild={true}>
129
141
  {iconButton}
130
142
  </Tooltip>
131
143
  );
@@ -135,7 +147,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
135
147
  <Menu
136
148
  trigger={<IconButton
137
149
  size={iconSize}>
138
- <MoreVertIcon/>
150
+ <MoreVertIcon />
139
151
  </IconButton>}>
140
152
  {collapsedActions.map((action, index) => (
141
153
  <MenuItem
@@ -183,7 +195,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
183
195
  <span className="min-w-0 truncate text-center">
184
196
  {entity
185
197
  ? entity.id
186
- : <Skeleton/>
198
+ : <Skeleton />
187
199
  }
188
200
  </span>
189
201
  </div>
@@ -192,4 +204,25 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
192
204
  </div>
193
205
  );
194
206
 
207
+ // Wrap with sortable outer div when sortable props are provided
208
+ // Remove tabIndex from attributes to avoid capturing focus before cell content
209
+ if (sortableNodeRef) {
210
+ const { tabIndex: _tabIndex, ...sortableAttrsWithoutTabIndex } = sortableAttributes ?? {};
211
+ return (
212
+ <div
213
+ ref={sortableNodeRef}
214
+ style={sortableStyle}
215
+ className={cls(
216
+ "flex-shrink-0",
217
+ frozen && "sticky left-0 z-10 bg-white dark:bg-surface-950"
218
+ )}
219
+ {...sortableAttrsWithoutTabIndex}
220
+ >
221
+ {content}
222
+ </div>
223
+ );
224
+ }
225
+
226
+ return content;
227
+
195
228
  };