@rebasepro/admin 0.2.1 → 0.2.4
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/{CollectionEditorDialog-BXIh2AXg.js → CollectionEditorDialog-D0VqpLPO.js} +73 -256
- package/dist/CollectionEditorDialog-D0VqpLPO.js.map +1 -0
- package/dist/{CollectionsStudioView-jR8iz_ja.js → CollectionsStudioView-Bc3Rxxc2.js} +5 -4
- package/dist/{CollectionsStudioView-jR8iz_ja.js.map → CollectionsStudioView-Bc3Rxxc2.js.map} +1 -1
- package/dist/{ExportCollectionAction-CMdiiv1L.js → ExportCollectionAction-Ckc-09BQ.js} +4 -3
- package/dist/ExportCollectionAction-Ckc-09BQ.js.map +1 -0
- package/dist/{ImportCollectionAction-C05lE0IW.js → ImportCollectionAction-BqjIrC3Z.js} +3 -2
- package/dist/{ImportCollectionAction-C05lE0IW.js.map → ImportCollectionAction-BqjIrC3Z.js.map} +1 -1
- package/dist/{PropertyEditView-BB5xjnhZ.js → PropertyEditView-CvRSV-A2.js} +430 -445
- package/dist/PropertyEditView-CvRSV-A2.js.map +1 -0
- package/dist/collection_editor/ConfigControllerProvider.d.ts +0 -5
- package/dist/collection_editor/index.d.ts +0 -1
- package/dist/collection_editor/types/collection_editor_controller.d.ts +0 -2
- package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +3 -3
- package/dist/collection_editor/ui/collection_editor/properties/RelationPropertyField.d.ts +1 -7
- package/dist/collection_editor_ui.js +3 -3
- package/dist/components/ArrayContainer.d.ts +2 -2
- package/dist/components/DefaultAppBar.d.ts +18 -1
- package/dist/components/DefaultDrawer.d.ts +51 -3
- package/dist/components/EntityCollectionTable/fields/TableStorageUpload.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
- package/dist/components/EntityCollectionTable/table_bindings.d.ts +4 -3
- package/dist/components/EntityCollectionView/hooks/useKanbanDragAndDrop.d.ts +4 -3
- package/dist/components/EntityEditView.d.ts +2 -1
- package/dist/components/HomePage/HomePageDnD.d.ts +3 -3
- package/dist/components/PropertyCollectionView.d.ts +1 -1
- package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
- package/dist/components/SelectableTable/SelectionStore.d.ts +4 -1
- package/dist/components/SelectableTable/filters/BooleanFilterField.d.ts +2 -2
- package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -2
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -2
- package/dist/components/SelectableTable/filters/StringNumberFilterField.d.ts +2 -2
- package/dist/components/admin/RolesView.d.ts +3 -3
- package/dist/components/admin/UsersView.d.ts +3 -3
- package/dist/components/app/Drawer.d.ts +8 -1
- package/dist/data_export/export/export.d.ts +3 -3
- package/dist/editor/components/editor-bubble.d.ts +5 -1
- package/dist/editor/components/image-bubble.d.ts +5 -1
- package/dist/editor/components/index.d.ts +3 -3
- package/dist/editor/components/table-bubble.d.ts +5 -1
- package/dist/editor/nodeViews/ReactNodeView.d.ts +4 -1
- package/dist/editor/useProseMirror.d.ts +2 -2
- package/dist/editor/utils/remove_classes.d.ts +1 -1
- package/dist/editor.js +15 -14
- package/dist/editor.js.map +1 -1
- package/dist/form/EntityForm.d.ts +2 -2
- package/dist/form/components/StorageUploadProgress.d.ts +2 -2
- package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
- package/dist/form/validation.d.ts +3 -3
- package/dist/hooks/navigation/useResolvedCollections.d.ts +6 -0
- package/dist/hooks/navigation/useResolvedViews.d.ts +3 -4
- package/dist/{index-BAM9KCmM.js → index-BCcLwgfe.js} +3 -2
- package/dist/{index-BAM9KCmM.js.map → index-BCcLwgfe.js.map} +1 -1
- package/dist/{index-D5OQhv-T.js → index-DY2k5TtG.js} +3 -3
- package/dist/index-DY2k5TtG.js.map +1 -0
- package/dist/{index-CoSNm3e3.js → index-UQOMHwt1.js} +3 -3
- package/dist/index-UQOMHwt1.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2813 -372
- package/dist/index.js.map +1 -1
- package/dist/{markdown-z2Ir7Cgo.js → markdown-DD2JDU1X.js} +2 -2
- package/dist/markdown-DD2JDU1X.js.map +1 -0
- package/dist/preview/components/UrlComponentPreview.d.ts +1 -0
- package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
- package/dist/types/components/EntityFormProps.d.ts +2 -2
- package/dist/types/fields.d.ts +1 -1
- package/dist/{util-DtbWD7LF.js → util-ZM9gQuCv.js} +2104 -2071
- package/dist/util-ZM9gQuCv.js.map +1 -0
- package/package.json +10 -9
- package/src/collection_editor/ConfigControllerProvider.tsx +3 -13
- package/src/collection_editor/index.ts +1 -3
- package/src/collection_editor/types/collection_editor_controller.tsx +0 -3
- package/src/collection_editor/ui/EditorCollectionAction.tsx +1 -6
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +1 -6
- package/src/collection_editor/ui/EditorEntityAction.tsx +1 -6
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +7 -14
- package/src/collection_editor/ui/NewCollectionCard.tsx +1 -5
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +3 -8
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +1 -10
- package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +8 -12
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +21 -21
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +4 -4
- package/src/collection_editor/ui/collection_editor/EnumForm.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx +8 -8
- package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +37 -57
- package/src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +8 -8
- package/src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx +5 -5
- package/src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx +3 -2
- package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +4 -7
- package/src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +4 -4
- package/src/collection_editor/validateCollectionJson.ts +88 -1
- package/src/components/ArrayContainer.tsx +3 -3
- package/src/components/DefaultAppBar.tsx +52 -31
- package/src/components/DefaultDrawer.tsx +279 -66
- package/src/components/DrawerNavigationItem.tsx +1 -1
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +6 -5
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +9 -7
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -5
- package/src/components/EntityCollectionTable/fields/VirtualTableNumberInput.tsx +12 -9
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +2 -2
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -1
- package/src/components/EntityCollectionTable/table_bindings.tsx +5 -4
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +6 -4
- package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -1
- package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +7 -6
- package/src/components/EntityDetailView.tsx +46 -24
- package/src/components/EntityEditView.tsx +51 -28
- package/src/components/EntityEditViewFormActions.tsx +4 -4
- package/src/components/EntityPreview.tsx +9 -4
- package/src/components/HomePage/HomePageDnD.tsx +3 -2
- package/src/components/PropertyCollectionView.tsx +1 -1
- package/src/components/PropertyIdCopyTooltip.tsx +1 -1
- package/src/components/RebaseLayout.tsx +5 -1
- package/src/components/RebaseNavigation.tsx +2 -2
- package/src/components/RebaseRouteDefs.tsx +4 -7
- package/src/components/RebaseShell.tsx +16 -13
- package/src/components/SearchIconsView.tsx +1 -8
- package/src/components/SelectableTable/SelectableTable.tsx +8 -11
- package/src/components/SelectableTable/SelectionStore.ts +1 -1
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +3 -3
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +3 -3
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +5 -5
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +3 -3
- package/src/components/SideEntityProvider.tsx +2 -1
- package/src/components/admin/RolesView.tsx +7 -2
- package/src/components/admin/UsersView.tsx +12 -6
- package/src/components/app/Drawer.tsx +9 -1
- package/src/components/app/Scaffold.tsx +5 -1
- package/src/data_export/export/export.ts +17 -17
- package/src/data_import/components/DataNewPropertiesMapping.tsx +1 -1
- package/src/editor/components/editor-bubble.tsx +32 -9
- package/src/editor/components/image-bubble.tsx +27 -11
- package/src/editor/components/index.ts +3 -3
- package/src/editor/components/table-bubble.tsx +79 -17
- package/src/editor/extensions/HighlightDecorationExtension.ts +3 -2
- package/src/editor/nodeViews/ReactNodeView.tsx +1 -1
- package/src/editor/nodeViews/TaskItemComponent.tsx +9 -8
- package/src/editor/schema.ts +135 -59
- package/src/editor/selectors/link-selector.tsx +8 -5
- package/src/editor/useProseMirror.ts +2 -2
- package/src/editor/utils/remove_classes.ts +6 -5
- package/src/form/EntityForm.tsx +15 -15
- package/src/form/EntityFormActions.tsx +2 -2
- package/src/form/PropertyFieldBinding.tsx +64 -64
- package/src/form/components/FieldHelperText.tsx +4 -4
- package/src/form/components/StorageUploadProgress.tsx +2 -2
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
- package/src/form/field_bindings/BlockFieldBinding.tsx +54 -53
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +290 -289
- package/src/form/field_bindings/MapFieldBinding.tsx +2 -2
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +2 -2
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +8 -6
- package/src/form/field_bindings/RelationFieldBinding.tsx +4 -4
- package/src/form/field_bindings/RepeatFieldBinding.tsx +1 -1
- package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +84 -84
- package/src/form/field_bindings/SwitchFieldBinding.tsx +16 -16
- package/src/form/field_bindings/TextFieldBinding.tsx +77 -73
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +17 -17
- package/src/form/validation.ts +43 -43
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +3 -5
- package/src/hooks/navigation/useResolvedCollections.ts +27 -7
- package/src/hooks/navigation/useResolvedViews.tsx +24 -44
- package/src/index.ts +2 -0
- package/src/preview/PropertyPreview.tsx +2 -2
- package/src/preview/components/ImagePreview.tsx +2 -1
- package/src/preview/components/UrlComponentPreview.tsx +11 -2
- package/src/preview/components/UserPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -4
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +3 -3
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +3 -3
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +3 -2
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +6 -8
- package/src/preview/property_previews/ArrayPropertyEnumPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +3 -3
- package/src/preview/property_previews/MapPropertyPreview.tsx +4 -3
- package/src/preview/property_previews/NumberPropertyPreview.tsx +5 -3
- package/src/preview/property_previews/StringPropertyPreview.tsx +10 -8
- package/src/types/components/EntityFormActionsProps.tsx +1 -1
- package/src/types/components/EntityFormProps.tsx +2 -2
- package/src/types/fields.tsx +2 -2
- package/dist/CollectionEditorDialog-BXIh2AXg.js.map +0 -1
- package/dist/ContentHomePage-BQZWuOFb.js +0 -1784
- package/dist/ContentHomePage-BQZWuOFb.js.map +0 -1
- package/dist/ExportCollectionAction-CMdiiv1L.js.map +0 -1
- package/dist/PropertyEditView-BB5xjnhZ.js.map +0 -1
- package/dist/RoleChip-QtUFXeTp.js +0 -67
- package/dist/RoleChip-QtUFXeTp.js.map +0 -1
- package/dist/RolesView-CULIHWZ9.js +0 -437
- package/dist/RolesView-CULIHWZ9.js.map +0 -1
- package/dist/UsersView-D7_AtJ44.js +0 -408
- package/dist/UsersView-D7_AtJ44.js.map +0 -1
- package/dist/collection_editor/types/config_permissions.d.ts +0 -19
- package/dist/index-CoSNm3e3.js.map +0 -1
- package/dist/index-D5OQhv-T.js.map +0 -1
- package/dist/markdown-z2Ir7Cgo.js.map +0 -1
- package/dist/util-DtbWD7LF.js.map +0 -1
- package/src/collection_editor/types/config_permissions.ts +0 -20
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { forwardRef, useEffect, useRef, useState } from "react";
|
|
2
2
|
import { useProseMirrorContext } from "../hooks/useProseMirrorContext";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
autoUpdate,
|
|
5
|
+
computePosition,
|
|
6
|
+
flip,
|
|
7
|
+
offset,
|
|
8
|
+
shift,
|
|
9
|
+
type VirtualElement,
|
|
10
|
+
type Placement
|
|
11
|
+
} from "@floating-ui/dom";
|
|
4
12
|
import { IconButton, Tooltip, defaultBorderMixin, cls } from "@rebasepro/ui";
|
|
5
13
|
import { useTranslation } from "@rebasepro/core";
|
|
6
14
|
import {
|
|
@@ -14,9 +22,8 @@ import {
|
|
|
14
22
|
} from "prosemirror-tables";
|
|
15
23
|
import { EditorState } from "prosemirror-state";
|
|
16
24
|
|
|
17
|
-
|
|
18
25
|
export interface TableBubbleProps {
|
|
19
|
-
options?:
|
|
26
|
+
options?: { placement?: Placement; offset?: number };
|
|
20
27
|
className?: string;
|
|
21
28
|
}
|
|
22
29
|
|
|
@@ -35,8 +42,14 @@ const isSelectionInTable = (state: EditorState) => {
|
|
|
35
42
|
// Wait, I will use generic SVGs for these since I don't know if @rebasepro/ui has them.
|
|
36
43
|
|
|
37
44
|
export const TableBubble = forwardRef<HTMLDivElement, TableBubbleProps>(
|
|
38
|
-
({
|
|
39
|
-
|
|
45
|
+
({
|
|
46
|
+
options,
|
|
47
|
+
className
|
|
48
|
+
}, ref) => {
|
|
49
|
+
const {
|
|
50
|
+
view,
|
|
51
|
+
state
|
|
52
|
+
} = useProseMirrorContext();
|
|
40
53
|
const { t } = useTranslation();
|
|
41
54
|
const menuRef = useRef<HTMLDivElement>(null);
|
|
42
55
|
const [show, setShow] = useState(false);
|
|
@@ -49,7 +62,10 @@ export const TableBubble = forwardRef<HTMLDivElement, TableBubbleProps>(
|
|
|
49
62
|
useEffect(() => {
|
|
50
63
|
if (!show || !view || !state || !menuRef.current) return;
|
|
51
64
|
|
|
52
|
-
const {
|
|
65
|
+
const {
|
|
66
|
+
from,
|
|
67
|
+
to
|
|
68
|
+
} = state.selection;
|
|
53
69
|
|
|
54
70
|
// Safety measure: if view.docView is destroyed, coordsAtPos might crash
|
|
55
71
|
if (view.isDestroyed) return;
|
|
@@ -90,7 +106,10 @@ export const TableBubble = forwardRef<HTMLDivElement, TableBubbleProps>(
|
|
|
90
106
|
placement: options?.placement || "top",
|
|
91
107
|
middleware: [offset(options?.offset || 8), flip(), shift()],
|
|
92
108
|
strategy: "fixed"
|
|
93
|
-
}).then(({
|
|
109
|
+
}).then(({
|
|
110
|
+
x,
|
|
111
|
+
y
|
|
112
|
+
}) => {
|
|
94
113
|
if (menuRef.current) {
|
|
95
114
|
Object.assign(menuRef.current.style, {
|
|
96
115
|
left: `${x}px`,
|
|
@@ -113,9 +132,11 @@ export const TableBubble = forwardRef<HTMLDivElement, TableBubbleProps>(
|
|
|
113
132
|
return (
|
|
114
133
|
<div
|
|
115
134
|
ref={menuRef}
|
|
116
|
-
style={{
|
|
117
|
-
|
|
118
|
-
|
|
135
|
+
style={{
|
|
136
|
+
visibility: "hidden",
|
|
137
|
+
position: "fixed",
|
|
138
|
+
zIndex: 50
|
|
139
|
+
}}
|
|
119
140
|
className={cls("flex flex-row gap-1 p-1 rounded-lg border bg-white dark:bg-surface-800 shadow-lg", defaultBorderMixin, className)}
|
|
120
141
|
onMouseDown={(e) => {
|
|
121
142
|
// Prevent mousedown from stealing focus from the editor
|
|
@@ -125,17 +146,34 @@ zIndex: 50 }}
|
|
|
125
146
|
<div className="flex gap-1 border-r pr-1 mr-1 dark:border-gray-700">
|
|
126
147
|
<Tooltip title={t("add_row_before")}>
|
|
127
148
|
<IconButton size="small" onClick={() => executeCommand(addRowBefore)}>
|
|
128
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
149
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
150
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
151
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
152
|
+
<line x1="12" y1="8" x2="12" y2="16"></line>
|
|
153
|
+
<line x1="8" y1="12" x2="16" y2="12"></line>
|
|
154
|
+
<line x1="3" y1="9" x2="21" y2="9"></line>
|
|
155
|
+
</svg>
|
|
129
156
|
</IconButton>
|
|
130
157
|
</Tooltip>
|
|
131
158
|
<Tooltip title={t("add_row_after")}>
|
|
132
159
|
<IconButton size="small" onClick={() => executeCommand(addRowAfter)}>
|
|
133
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
160
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
161
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
162
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
163
|
+
<line x1="12" y1="12" x2="12" y2="20"></line>
|
|
164
|
+
<line x1="8" y1="16" x2="16" y2="16"></line>
|
|
165
|
+
<line x1="3" y1="15" x2="21" y2="15"></line>
|
|
166
|
+
</svg>
|
|
134
167
|
</IconButton>
|
|
135
168
|
</Tooltip>
|
|
136
169
|
<Tooltip title={t("delete_row")}>
|
|
137
170
|
<IconButton size="small" onClick={() => executeCommand(deleteRow)}>
|
|
138
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
171
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
172
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
173
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
174
|
+
<line x1="3" y1="12" x2="21" y2="12"></line>
|
|
175
|
+
<line x1="8" y1="12" x2="16" y2="12"></line>
|
|
176
|
+
</svg>
|
|
139
177
|
</IconButton>
|
|
140
178
|
</Tooltip>
|
|
141
179
|
</div>
|
|
@@ -143,24 +181,48 @@ zIndex: 50 }}
|
|
|
143
181
|
<div className="flex gap-1 border-r pr-1 mr-1 dark:border-gray-700">
|
|
144
182
|
<Tooltip title={t("add_column_before")}>
|
|
145
183
|
<IconButton size="small" onClick={() => executeCommand(addColumnBefore)}>
|
|
146
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
184
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
185
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
186
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
187
|
+
<line x1="8" y1="12" x2="16" y2="12"></line>
|
|
188
|
+
<line x1="12" y1="8" x2="12" y2="16"></line>
|
|
189
|
+
<line x1="9" y1="3" x2="9" y2="21"></line>
|
|
190
|
+
</svg>
|
|
147
191
|
</IconButton>
|
|
148
192
|
</Tooltip>
|
|
149
193
|
<Tooltip title={t("add_column_after")}>
|
|
150
194
|
<IconButton size="small" onClick={() => executeCommand(addColumnAfter)}>
|
|
151
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
195
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
196
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
197
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
198
|
+
<line x1="12" y1="12" x2="20" y2="12"></line>
|
|
199
|
+
<line x1="16" y1="8" x2="16" y2="16"></line>
|
|
200
|
+
<line x1="15" y1="3" x2="15" y2="21"></line>
|
|
201
|
+
</svg>
|
|
152
202
|
</IconButton>
|
|
153
203
|
</Tooltip>
|
|
154
204
|
<Tooltip title={t("delete_column")}>
|
|
155
205
|
<IconButton size="small" onClick={() => executeCommand(deleteColumn)}>
|
|
156
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
206
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
207
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
208
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
209
|
+
<line x1="12" y1="3" x2="12" y2="21"></line>
|
|
210
|
+
<line x1="12" y1="8" x2="12" y2="16"></line>
|
|
211
|
+
</svg>
|
|
157
212
|
</IconButton>
|
|
158
213
|
</Tooltip>
|
|
159
214
|
</div>
|
|
160
215
|
|
|
161
216
|
<Tooltip title={t("delete_table")}>
|
|
162
217
|
<IconButton size="small" onClick={() => executeCommand(deleteTable)}>
|
|
163
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
218
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
219
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
220
|
+
<polyline points="3 6 5 6 21 6"></polyline>
|
|
221
|
+
<path
|
|
222
|
+
d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
|
|
223
|
+
<line x1="10" y1="11" x2="10" y2="17"></line>
|
|
224
|
+
<line x1="14" y1="11" x2="14" y2="17"></line>
|
|
225
|
+
</svg>
|
|
164
226
|
</IconButton>
|
|
165
227
|
</Tooltip>
|
|
166
228
|
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Plugin, PluginKey, Transaction, EditorState } from "prosemirror-state";
|
|
2
2
|
import { Decoration, DecorationSet } from "prosemirror-view";
|
|
3
|
+
import { Node as ProseMirrorNode } from "prosemirror-model";
|
|
3
4
|
|
|
4
5
|
export interface HighlightRange {
|
|
5
6
|
from: number
|
|
@@ -13,8 +14,8 @@ interface AutocompleteHighlightState {
|
|
|
13
14
|
|
|
14
15
|
export const highlightDecorationKey = new PluginKey<AutocompleteHighlightState>("highlightDecoration");
|
|
15
16
|
|
|
16
|
-
function buildDecorationSet(highlight:
|
|
17
|
-
const decorations: [
|
|
17
|
+
function buildDecorationSet(highlight: HighlightRange | undefined, doc: ProseMirrorNode) {
|
|
18
|
+
const decorations: Decoration[] = [];
|
|
18
19
|
|
|
19
20
|
if (highlight) {
|
|
20
21
|
decorations.push(
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { Checkbox, Label } from "@rebasepro/ui";
|
|
2
3
|
import { ReactNodeViewProps } from "./ReactNodeView";
|
|
3
4
|
|
|
4
5
|
export const TaskItemComponent: React.FC<ReactNodeViewProps> = ({ node, view, getPos }) => {
|
|
5
6
|
const checked = node.attrs.checked;
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
+
const handleCheckedChange = (isChecked: boolean) => {
|
|
8
9
|
const pos = getPos();
|
|
9
10
|
if (typeof pos !== "number") return;
|
|
10
11
|
|
|
11
12
|
view.dispatch(
|
|
12
13
|
view.state.tr.setNodeMarkup(pos, undefined, {
|
|
13
14
|
...node.attrs,
|
|
14
|
-
checked:
|
|
15
|
+
checked: isChecked
|
|
15
16
|
})
|
|
16
17
|
);
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
return (
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
type="checkbox"
|
|
21
|
+
<Label contentEditable={false} className="flex items-start select-none px-1 cursor-pointer">
|
|
22
|
+
<Checkbox
|
|
23
23
|
checked={checked}
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
onCheckedChange={handleCheckedChange}
|
|
25
|
+
padding={false}
|
|
26
|
+
size="small"
|
|
26
27
|
/>
|
|
27
|
-
</
|
|
28
|
+
</Label>
|
|
28
29
|
);
|
|
29
30
|
};
|
package/src/editor/schema.ts
CHANGED
|
@@ -23,41 +23,65 @@ const marks: { [key: string]: MarkSpec } = {
|
|
|
23
23
|
}
|
|
24
24
|
],
|
|
25
25
|
toDOM(node) {
|
|
26
|
-
const {
|
|
27
|
-
|
|
28
|
-
title,
|
|
29
|
-
target
|
|
30
|
-
|
|
26
|
+
const {
|
|
27
|
+
href,
|
|
28
|
+
title,
|
|
29
|
+
target
|
|
30
|
+
} = node.attrs;
|
|
31
|
+
return ["a", {
|
|
32
|
+
href,
|
|
33
|
+
title,
|
|
34
|
+
target,
|
|
35
|
+
class: "text-surface-700 dark:text-surface-accent-200 underline underline-offset-[3px] hover:text-primary transition-colors cursor-pointer"
|
|
36
|
+
}, 0];
|
|
31
37
|
}
|
|
32
38
|
},
|
|
33
39
|
bold: {
|
|
34
40
|
parseDOM: [
|
|
35
41
|
{ tag: "strong" },
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
+
{
|
|
43
|
+
tag: "b",
|
|
44
|
+
getAttrs: (node: HTMLElement | string) => typeof node !== "string" && node.style.fontWeight !== "normal" && null
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
style: "font-weight=400",
|
|
48
|
+
clearMark: m => m.type.name === "bold"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
style: "font-weight",
|
|
52
|
+
getAttrs: (value: string | HTMLElement) => typeof value === "string" && /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null
|
|
53
|
+
}
|
|
42
54
|
],
|
|
43
|
-
toDOM() {
|
|
55
|
+
toDOM() {
|
|
56
|
+
return ["strong", 0];
|
|
57
|
+
}
|
|
44
58
|
},
|
|
45
59
|
italic: {
|
|
46
60
|
parseDOM: [{ tag: "i" }, { tag: "em" }, { style: "font-style=italic" }],
|
|
47
|
-
toDOM() {
|
|
61
|
+
toDOM() {
|
|
62
|
+
return ["em", 0];
|
|
63
|
+
}
|
|
48
64
|
},
|
|
49
65
|
strike: {
|
|
50
66
|
parseDOM: [{ tag: "s" }, { tag: "del" }, { tag: "strike" }, { style: "text-decoration=line-through" }],
|
|
51
|
-
toDOM() {
|
|
67
|
+
toDOM() {
|
|
68
|
+
return ["s", 0];
|
|
69
|
+
}
|
|
52
70
|
},
|
|
53
71
|
underline: {
|
|
54
72
|
parseDOM: [{ tag: "u" }, { style: "text-decoration=underline" }],
|
|
55
|
-
toDOM() {
|
|
73
|
+
toDOM() {
|
|
74
|
+
return ["u", 0];
|
|
75
|
+
}
|
|
56
76
|
},
|
|
57
77
|
code: {
|
|
58
78
|
parseDOM: [{ tag: "code" }],
|
|
59
|
-
toDOM() {
|
|
60
|
-
|
|
79
|
+
toDOM() {
|
|
80
|
+
return ["code", {
|
|
81
|
+
class: "rounded-md bg-surface-accent-50 dark:bg-surface-700 px-1.5 py-1 font-mono font-medium",
|
|
82
|
+
spellcheck: "false"
|
|
83
|
+
}, 0];
|
|
84
|
+
}
|
|
61
85
|
},
|
|
62
86
|
textStyle: {
|
|
63
87
|
attrs: { color: { default: null } },
|
|
@@ -88,8 +112,10 @@ spellcheck: "false" }, 0]; }
|
|
|
88
112
|
}
|
|
89
113
|
],
|
|
90
114
|
toDOM(mark) {
|
|
91
|
-
return ["mark", mark.attrs.color ? {
|
|
92
|
-
|
|
115
|
+
return ["mark", mark.attrs.color ? {
|
|
116
|
+
style: `background-color: ${mark.attrs.color}; color: inherit;`,
|
|
117
|
+
"data-color": mark.attrs.color
|
|
118
|
+
} : {}, 0];
|
|
93
119
|
}
|
|
94
120
|
}
|
|
95
121
|
};
|
|
@@ -102,7 +128,9 @@ const nodes: { [key: string]: NodeSpec } = {
|
|
|
102
128
|
content: "inline*",
|
|
103
129
|
group: "block",
|
|
104
130
|
parseDOM: [{ tag: "p" }],
|
|
105
|
-
toDOM() {
|
|
131
|
+
toDOM() {
|
|
132
|
+
return ["p", 0];
|
|
133
|
+
}
|
|
106
134
|
},
|
|
107
135
|
text: {
|
|
108
136
|
group: "inline"
|
|
@@ -112,7 +140,9 @@ const nodes: { [key: string]: NodeSpec } = {
|
|
|
112
140
|
group: "block",
|
|
113
141
|
defining: true,
|
|
114
142
|
parseDOM: [{ tag: "blockquote" }],
|
|
115
|
-
toDOM() {
|
|
143
|
+
toDOM() {
|
|
144
|
+
return ["blockquote", { class: "border-l-4 border-primary" }, 0];
|
|
145
|
+
}
|
|
116
146
|
},
|
|
117
147
|
heading: {
|
|
118
148
|
attrs: { level: { default: 1 } },
|
|
@@ -120,25 +150,41 @@ const nodes: { [key: string]: NodeSpec } = {
|
|
|
120
150
|
group: "block",
|
|
121
151
|
defining: true,
|
|
122
152
|
parseDOM: [
|
|
123
|
-
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
{
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
153
|
+
{
|
|
154
|
+
tag: "h1",
|
|
155
|
+
attrs: { level: 1 }
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
tag: "h2",
|
|
159
|
+
attrs: { level: 2 }
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
tag: "h3",
|
|
163
|
+
attrs: { level: 3 }
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
tag: "h4",
|
|
167
|
+
attrs: { level: 4 }
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
tag: "h5",
|
|
171
|
+
attrs: { level: 5 }
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
tag: "h6",
|
|
175
|
+
attrs: { level: 6 }
|
|
176
|
+
}
|
|
135
177
|
],
|
|
136
|
-
toDOM(node) {
|
|
178
|
+
toDOM(node) {
|
|
179
|
+
return ["h" + node.attrs.level, 0];
|
|
180
|
+
}
|
|
137
181
|
},
|
|
138
182
|
horizontal_rule: {
|
|
139
183
|
group: "block",
|
|
140
184
|
parseDOM: [{ tag: "hr" }],
|
|
141
|
-
toDOM() {
|
|
185
|
+
toDOM() {
|
|
186
|
+
return ["hr", { class: "mt-4 mb-6 border-t border-solid border-gray-200 dark:border-gray-800" }];
|
|
187
|
+
}
|
|
142
188
|
},
|
|
143
189
|
code_block: {
|
|
144
190
|
content: "text*",
|
|
@@ -148,10 +194,14 @@ attrs: { level: 6 } }
|
|
|
148
194
|
defining: true,
|
|
149
195
|
attrs: { language: { default: null } },
|
|
150
196
|
parseDOM: [
|
|
151
|
-
{
|
|
152
|
-
|
|
197
|
+
{
|
|
198
|
+
tag: "pre",
|
|
199
|
+
preserveWhitespace: "full"
|
|
200
|
+
}
|
|
153
201
|
],
|
|
154
|
-
toDOM(node) {
|
|
202
|
+
toDOM(node) {
|
|
203
|
+
return ["pre", { class: "rounded bg-blue-50 dark:bg-surface-700 border border-solid border-gray-200 dark:border-gray-800 p-5 font-mono font-medium text-gray-800 dark:text-gray-200" }, ["code", 0]];
|
|
204
|
+
}
|
|
155
205
|
},
|
|
156
206
|
image: {
|
|
157
207
|
inline: false,
|
|
@@ -176,18 +226,26 @@ preserveWhitespace: "full" }
|
|
|
176
226
|
}
|
|
177
227
|
],
|
|
178
228
|
toDOM(node) {
|
|
179
|
-
const {
|
|
180
|
-
|
|
181
|
-
alt,
|
|
182
|
-
title
|
|
183
|
-
|
|
229
|
+
const {
|
|
230
|
+
src,
|
|
231
|
+
alt,
|
|
232
|
+
title
|
|
233
|
+
} = node.attrs;
|
|
234
|
+
return ["img", {
|
|
235
|
+
src,
|
|
236
|
+
alt,
|
|
237
|
+
title,
|
|
238
|
+
class: "rounded-lg max-w-full !m-0"
|
|
239
|
+
}];
|
|
184
240
|
}
|
|
185
241
|
},
|
|
186
242
|
bullet_list: {
|
|
187
243
|
content: "list_item+",
|
|
188
244
|
group: "block",
|
|
189
245
|
parseDOM: [{ tag: "ul" }],
|
|
190
|
-
toDOM() {
|
|
246
|
+
toDOM() {
|
|
247
|
+
return ["ul", { class: "list-disc list-outside leading-3 -mt-2" }, 0];
|
|
248
|
+
}
|
|
191
249
|
},
|
|
192
250
|
ordered_list: {
|
|
193
251
|
content: "list_item+",
|
|
@@ -203,22 +261,30 @@ class: "rounded-lg max-w-full !m-0" }];
|
|
|
203
261
|
}
|
|
204
262
|
],
|
|
205
263
|
toDOM(node) {
|
|
206
|
-
return node.attrs.order === 1 ? ["ol", { class: "list-decimal list-outside leading-3 -mt-2" }, 0] : ["ol", {
|
|
207
|
-
|
|
264
|
+
return node.attrs.order === 1 ? ["ol", { class: "list-decimal list-outside leading-3 -mt-2" }, 0] : ["ol", {
|
|
265
|
+
start: node.attrs.order,
|
|
266
|
+
class: "list-decimal list-outside leading-3 -mt-2"
|
|
267
|
+
}, 0];
|
|
208
268
|
}
|
|
209
269
|
},
|
|
210
270
|
list_item: {
|
|
211
271
|
content: "paragraph block*",
|
|
212
272
|
parseDOM: [{ tag: "li" }],
|
|
213
|
-
toDOM() {
|
|
273
|
+
toDOM() {
|
|
274
|
+
return ["li", { class: "leading-normal -mb-2" }, 0];
|
|
275
|
+
},
|
|
214
276
|
defining: true
|
|
215
277
|
},
|
|
216
278
|
task_list: {
|
|
217
279
|
group: "block",
|
|
218
280
|
content: "task_item+",
|
|
219
|
-
parseDOM: [{ tag:
|
|
220
|
-
toDOM() {
|
|
221
|
-
|
|
281
|
+
parseDOM: [{ tag: "ul[data-type=\"taskList\"]" }],
|
|
282
|
+
toDOM() {
|
|
283
|
+
return ["ul", {
|
|
284
|
+
"data-type": "taskList",
|
|
285
|
+
class: "not-prose"
|
|
286
|
+
}, 0];
|
|
287
|
+
}
|
|
222
288
|
},
|
|
223
289
|
task_item: {
|
|
224
290
|
content: "paragraph block*",
|
|
@@ -226,7 +292,7 @@ class: "not-prose" }, 0]; }
|
|
|
226
292
|
attrs: { checked: { default: false } },
|
|
227
293
|
parseDOM: [
|
|
228
294
|
{
|
|
229
|
-
tag:
|
|
295
|
+
tag: "li[data-type=\"taskItem\"]",
|
|
230
296
|
getAttrs(dom: HTMLElement | string) {
|
|
231
297
|
if (typeof dom === "string") return false;
|
|
232
298
|
return { checked: dom.getAttribute("data-checked") === "true" };
|
|
@@ -234,9 +300,11 @@ class: "not-prose" }, 0]; }
|
|
|
234
300
|
}
|
|
235
301
|
],
|
|
236
302
|
toDOM(node) {
|
|
237
|
-
return ["li", {
|
|
238
|
-
"data-
|
|
239
|
-
|
|
303
|
+
return ["li", {
|
|
304
|
+
"data-type": "taskItem",
|
|
305
|
+
"data-checked": node.attrs.checked ? "true" : "false",
|
|
306
|
+
class: "flex items-start my-4"
|
|
307
|
+
}, 0];
|
|
240
308
|
}
|
|
241
309
|
},
|
|
242
310
|
hard_break: {
|
|
@@ -244,7 +312,9 @@ class: "flex items-start my-4" }, 0];
|
|
|
244
312
|
group: "inline",
|
|
245
313
|
selectable: false,
|
|
246
314
|
parseDOM: [{ tag: "br" }],
|
|
247
|
-
toDOM() {
|
|
315
|
+
toDOM() {
|
|
316
|
+
return ["br"];
|
|
317
|
+
}
|
|
248
318
|
},
|
|
249
319
|
...tableNodes({
|
|
250
320
|
tableGroup: "block",
|
|
@@ -252,12 +322,18 @@ class: "flex items-start my-4" }, 0];
|
|
|
252
322
|
cellAttributes: {
|
|
253
323
|
background: {
|
|
254
324
|
default: null,
|
|
255
|
-
getFromDOM(dom: HTMLElement) {
|
|
256
|
-
|
|
325
|
+
getFromDOM(dom: HTMLElement) {
|
|
326
|
+
return dom.style.backgroundColor || null
|
|
327
|
+
},
|
|
328
|
+
setDOMAttr(value: unknown, attrs: any) {
|
|
329
|
+
if (value && typeof value === "string") attrs.style = (attrs.style || "") + `background-color: ${value};`
|
|
330
|
+
}
|
|
257
331
|
}
|
|
258
332
|
}
|
|
259
333
|
})
|
|
260
334
|
};
|
|
261
335
|
|
|
262
|
-
export const schema = new Schema({
|
|
263
|
-
|
|
336
|
+
export const schema = new Schema({
|
|
337
|
+
nodes,
|
|
338
|
+
marks
|
|
339
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
|
-
import { Button, CheckIcon, cls, focusedDisabled, iconSize, Popover, Trash2Icon } from "@rebasepro/ui";
|
|
2
|
+
import { Button, CheckIcon, cls, focusedDisabled, iconSize, Popover, TextField, Trash2Icon } from "@rebasepro/ui";
|
|
3
3
|
import { useTranslation } from "@rebasepro/core";
|
|
4
4
|
import { useProseMirrorContext } from "../hooks/useProseMirrorContext";
|
|
5
5
|
import { getMarkAttributes, isMarkActive, setMark, unsetMark } from "../utils/prosemirror-utils";
|
|
@@ -48,7 +48,7 @@ export const LinkSelector = ({
|
|
|
48
48
|
|
|
49
49
|
if (!state || !view) return null;
|
|
50
50
|
|
|
51
|
-
const handleSubmit = (e:
|
|
51
|
+
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
|
52
52
|
e.preventDefault();
|
|
53
53
|
const value = inputRef.current?.value;
|
|
54
54
|
if (!value) return;
|
|
@@ -87,12 +87,15 @@ export const LinkSelector = ({
|
|
|
87
87
|
onSubmit={handleSubmit}
|
|
88
88
|
className="flex p-1 gap-1"
|
|
89
89
|
>
|
|
90
|
-
<
|
|
91
|
-
|
|
90
|
+
<TextField
|
|
91
|
+
inputRef={inputRef}
|
|
92
92
|
autoFocus={open}
|
|
93
93
|
placeholder={t("editor_paste_or_type_link")}
|
|
94
94
|
defaultValue={href}
|
|
95
|
-
|
|
95
|
+
size="small"
|
|
96
|
+
className="flex-grow text-surface-900 dark:text-white"
|
|
97
|
+
inputClassName={cls("bg-transparent p-1 text-sm outline-none", focusedDisabled)}
|
|
98
|
+
/>
|
|
96
99
|
|
|
97
100
|
{href ? (
|
|
98
101
|
<Button
|
|
@@ -7,11 +7,11 @@ import { removeClassesFromJson } from "./utils/remove_classes";
|
|
|
7
7
|
import { DOMParser as ProseMirrorDOMParser, DOMSerializer } from "prosemirror-model";
|
|
8
8
|
|
|
9
9
|
export interface UseProseMirrorOptions {
|
|
10
|
-
content?:
|
|
10
|
+
content?: unknown;
|
|
11
11
|
plugins?: Plugin[];
|
|
12
12
|
editable?: boolean;
|
|
13
13
|
onMarkdownContentChange?: (content: string) => void;
|
|
14
|
-
onJsonContentChange?: (content:
|
|
14
|
+
onJsonContentChange?: (content: unknown | null) => void;
|
|
15
15
|
onHtmlContentChange?: (content: string) => void;
|
|
16
16
|
version?: number;
|
|
17
17
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
export function removeClassesFromJson(jsonObj:
|
|
1
|
+
export function removeClassesFromJson(jsonObj: unknown): unknown {
|
|
2
2
|
// If it's an array, apply the function to each element
|
|
3
3
|
if (Array.isArray(jsonObj)) {
|
|
4
4
|
return jsonObj.map(item => removeClassesFromJson(item));
|
|
5
5
|
} else if (typeof jsonObj === "object" && jsonObj !== null) { // If it's an object, recurse through its properties
|
|
6
|
+
const obj = jsonObj as Record<string, unknown>;
|
|
6
7
|
// If the object has an `attrs` property and `class` field, delete the `class` field
|
|
7
|
-
if (
|
|
8
|
-
delete
|
|
8
|
+
if (obj.attrs && typeof obj.attrs === "object" && obj.attrs !== null && "class" in (obj.attrs as Record<string, unknown>)) {
|
|
9
|
+
delete (obj.attrs as Record<string, unknown>).class;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
// Apply the function recursively to object properties
|
|
12
|
-
Object.keys(
|
|
13
|
-
|
|
13
|
+
Object.keys(obj).forEach(key => {
|
|
14
|
+
obj[key] = removeClassesFromJson(obj[key]);
|
|
14
15
|
});
|
|
15
16
|
}
|
|
16
17
|
return jsonObj;
|