@elementor/editor-global-classes 4.2.0-888 → 4.2.0-895
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/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +120 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +117 -98
- package/dist/index.mjs.map +1 -1
- package/package.json +20 -20
- package/src/components/class-manager/class-manager-button.tsx +12 -64
- package/src/components/class-manager/class-manager-panel.tsx +20 -4
- package/src/load-existing-classes.ts +4 -2
- package/src/mcp-integration/mcp-manage-global-classes.ts +88 -54
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-global-classes",
|
|
3
|
-
"version": "4.2.0-
|
|
3
|
+
"version": "4.2.0-895",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -39,29 +39,29 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "4.2.0-
|
|
43
|
-
"@elementor/editor-current-user": "4.2.0-
|
|
44
|
-
"@elementor/editor-documents": "4.2.0-
|
|
45
|
-
"@elementor/editor-editing-panel": "4.2.0-
|
|
46
|
-
"@elementor/editor-mcp": "4.2.0-
|
|
47
|
-
"@elementor/editor-panels": "4.2.0-
|
|
48
|
-
"@elementor/editor-props": "4.2.0-
|
|
49
|
-
"@elementor/editor-variables": "4.2.0-
|
|
50
|
-
"@elementor/editor-styles": "4.2.0-
|
|
51
|
-
"@elementor/editor-canvas": "4.2.0-
|
|
52
|
-
"@elementor/editor-styles-repository": "4.2.0-
|
|
53
|
-
"@elementor/editor-ui": "4.2.0-
|
|
54
|
-
"@elementor/editor-v1-adapters": "4.2.0-
|
|
55
|
-
"@elementor/http-client": "4.2.0-
|
|
42
|
+
"@elementor/editor": "4.2.0-895",
|
|
43
|
+
"@elementor/editor-current-user": "4.2.0-895",
|
|
44
|
+
"@elementor/editor-documents": "4.2.0-895",
|
|
45
|
+
"@elementor/editor-editing-panel": "4.2.0-895",
|
|
46
|
+
"@elementor/editor-mcp": "4.2.0-895",
|
|
47
|
+
"@elementor/editor-panels": "4.2.0-895",
|
|
48
|
+
"@elementor/editor-props": "4.2.0-895",
|
|
49
|
+
"@elementor/editor-variables": "4.2.0-895",
|
|
50
|
+
"@elementor/editor-styles": "4.2.0-895",
|
|
51
|
+
"@elementor/editor-canvas": "4.2.0-895",
|
|
52
|
+
"@elementor/editor-styles-repository": "4.2.0-895",
|
|
53
|
+
"@elementor/editor-ui": "4.2.0-895",
|
|
54
|
+
"@elementor/editor-v1-adapters": "4.2.0-895",
|
|
55
|
+
"@elementor/http-client": "4.2.0-895",
|
|
56
56
|
"@elementor/icons": "~1.75.1",
|
|
57
|
-
"@elementor/query": "4.2.0-
|
|
58
|
-
"@elementor/schema": "4.2.0-
|
|
59
|
-
"@elementor/store": "4.2.0-
|
|
57
|
+
"@elementor/query": "4.2.0-895",
|
|
58
|
+
"@elementor/schema": "4.2.0-895",
|
|
59
|
+
"@elementor/store": "4.2.0-895",
|
|
60
60
|
"@elementor/ui": "1.37.5",
|
|
61
|
-
"@elementor/utils": "4.2.0-
|
|
61
|
+
"@elementor/utils": "4.2.0-895",
|
|
62
62
|
"@tanstack/react-virtual": "^3.13.24",
|
|
63
63
|
"@wordpress/i18n": "^5.13.0",
|
|
64
|
-
"@elementor/events": "4.2.0-
|
|
64
|
+
"@elementor/events": "4.2.0-895"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"react": "^18.3.1",
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
__useActiveDocument as useActiveDocument,
|
|
4
|
-
__useActiveDocumentActions as useActiveDocumentActions,
|
|
5
|
-
} from '@elementor/editor-documents';
|
|
6
2
|
import { useUserStylesCapability } from '@elementor/editor-styles-repository';
|
|
7
|
-
import { SaveChangesDialog, useDialog } from '@elementor/editor-ui';
|
|
8
3
|
import { IconButton, Tooltip } from '@elementor/ui';
|
|
9
4
|
import { __ } from '@wordpress/i18n';
|
|
10
5
|
|
|
@@ -13,17 +8,9 @@ import { usePrefetchCssClassUsage } from '../../hooks/use-prefetch-css-class-usa
|
|
|
13
8
|
import { trackGlobalClasses } from '../../utils/tracking';
|
|
14
9
|
import { FlippedColorSwatchIcon } from './flipped-color-swatch-icon';
|
|
15
10
|
|
|
16
|
-
const
|
|
17
|
-
trackGlobalClasses( {
|
|
18
|
-
event: 'classManagerOpened',
|
|
19
|
-
source: 'style-panel',
|
|
20
|
-
} );
|
|
21
|
-
};
|
|
11
|
+
const EVENT_TOGGLE_DESIGN_SYSTEM = 'elementor/toggle-design-system';
|
|
22
12
|
|
|
23
13
|
export const ClassManagerButton = () => {
|
|
24
|
-
const document = useActiveDocument();
|
|
25
|
-
const { save: saveDocument } = useActiveDocumentActions();
|
|
26
|
-
const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
|
|
27
14
|
const { prefetchClassesUsage } = usePrefetchCssClassUsage();
|
|
28
15
|
|
|
29
16
|
const { userCan } = useUserStylesCapability();
|
|
@@ -34,64 +21,25 @@ export const ClassManagerButton = () => {
|
|
|
34
21
|
return null;
|
|
35
22
|
}
|
|
36
23
|
|
|
37
|
-
const
|
|
24
|
+
const handleOpenPanel = () => {
|
|
38
25
|
window.dispatchEvent(
|
|
39
|
-
new CustomEvent(
|
|
26
|
+
new CustomEvent( EVENT_TOGGLE_DESIGN_SYSTEM, {
|
|
40
27
|
detail: { tab: 'classes' as const },
|
|
41
28
|
} )
|
|
42
29
|
);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const handleOpenPanel = () => {
|
|
46
|
-
if ( document?.isDirty ) {
|
|
47
|
-
openSaveChangesDialog();
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
toggleClassesManagerPanel();
|
|
52
30
|
|
|
53
|
-
|
|
31
|
+
trackGlobalClasses( {
|
|
32
|
+
event: 'classManagerOpened',
|
|
33
|
+
source: 'style-panel',
|
|
34
|
+
} );
|
|
54
35
|
prefetchClassesUsage();
|
|
55
36
|
};
|
|
56
37
|
|
|
57
38
|
return (
|
|
58
|
-
|
|
59
|
-
<
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
</Tooltip>
|
|
64
|
-
{ isSaveChangesDialogOpen && (
|
|
65
|
-
<SaveChangesDialog>
|
|
66
|
-
<SaveChangesDialog.Title>{ __( 'You have unsaved changes', 'elementor' ) }</SaveChangesDialog.Title>
|
|
67
|
-
<SaveChangesDialog.Content>
|
|
68
|
-
<SaveChangesDialog.ContentText sx={ { mb: 2 } }>
|
|
69
|
-
{ __(
|
|
70
|
-
"To open the Class Manager, save your page first. You can't continue without saving.",
|
|
71
|
-
'elementor'
|
|
72
|
-
) }
|
|
73
|
-
</SaveChangesDialog.ContentText>
|
|
74
|
-
</SaveChangesDialog.Content>
|
|
75
|
-
<SaveChangesDialog.Actions
|
|
76
|
-
actions={ {
|
|
77
|
-
cancel: {
|
|
78
|
-
label: __( 'Stay here', 'elementor' ),
|
|
79
|
-
action: closeSaveChangesDialog,
|
|
80
|
-
},
|
|
81
|
-
confirm: {
|
|
82
|
-
label: __( 'Save & Continue', 'elementor' ),
|
|
83
|
-
action: async () => {
|
|
84
|
-
await saveDocument();
|
|
85
|
-
closeSaveChangesDialog();
|
|
86
|
-
toggleClassesManagerPanel();
|
|
87
|
-
trackGlobalClassesButton();
|
|
88
|
-
prefetchClassesUsage();
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
} }
|
|
92
|
-
/>
|
|
93
|
-
</SaveChangesDialog>
|
|
94
|
-
) }
|
|
95
|
-
</>
|
|
39
|
+
<Tooltip title={ __( 'Class Manager', 'elementor' ) } placement="top">
|
|
40
|
+
<IconButton size="tiny" onClick={ handleOpenPanel } sx={ { marginInlineEnd: -0.75 } }>
|
|
41
|
+
<FlippedColorSwatchIcon fontSize="tiny" />
|
|
42
|
+
</IconButton>
|
|
43
|
+
</Tooltip>
|
|
96
44
|
);
|
|
97
45
|
};
|
|
@@ -37,18 +37,34 @@ type StopSyncConfirmationDialogProps = {
|
|
|
37
37
|
export type ClassManagerPanelEmbeddedProps = {
|
|
38
38
|
onRequestClose: () => void | Promise< void >;
|
|
39
39
|
onExposeCloseAttempt?: ( attemptClose: ( () => void ) | null ) => void;
|
|
40
|
+
isActive?: boolean;
|
|
40
41
|
};
|
|
41
42
|
|
|
42
|
-
export function ClassManagerPanelEmbedded( {
|
|
43
|
-
|
|
43
|
+
export function ClassManagerPanelEmbedded( {
|
|
44
|
+
onRequestClose,
|
|
45
|
+
onExposeCloseAttempt,
|
|
46
|
+
isActive,
|
|
47
|
+
}: ClassManagerPanelEmbeddedProps ) {
|
|
48
|
+
return (
|
|
49
|
+
<ClassManagerPanelContent
|
|
50
|
+
onRequestClose={ onRequestClose }
|
|
51
|
+
onExposeCloseAttempt={ onExposeCloseAttempt }
|
|
52
|
+
isActive={ isActive }
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
44
55
|
}
|
|
45
56
|
|
|
46
57
|
type ClassManagerPanelContentProps = {
|
|
47
58
|
onRequestClose: () => void | Promise< void >;
|
|
48
59
|
onExposeCloseAttempt?: ( attemptClose: ( () => void ) | null ) => void;
|
|
60
|
+
isActive?: boolean;
|
|
49
61
|
};
|
|
50
62
|
|
|
51
|
-
function ClassManagerPanelContent( {
|
|
63
|
+
function ClassManagerPanelContent( {
|
|
64
|
+
onRequestClose,
|
|
65
|
+
onExposeCloseAttempt,
|
|
66
|
+
isActive = true,
|
|
67
|
+
}: ClassManagerPanelContentProps ) {
|
|
52
68
|
const isDirty = useDirtyState();
|
|
53
69
|
const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
|
|
54
70
|
const [ stopSyncConfirmation, setStopSyncConfirmation ] = useState< string | null >( null );
|
|
@@ -192,7 +208,7 @@ function ClassManagerPanelContent( { onRequestClose, onExposeCloseAttempt }: Cla
|
|
|
192
208
|
</Stack>
|
|
193
209
|
</SearchAndFilterProvider>
|
|
194
210
|
</ErrorBoundary>
|
|
195
|
-
<ClassManagerIntroduction />
|
|
211
|
+
{ isActive && <ClassManagerIntroduction /> }
|
|
196
212
|
{ startSyncConfirmation && (
|
|
197
213
|
<StartSyncToV3Modal
|
|
198
214
|
externalOpen
|
|
@@ -40,8 +40,10 @@ async function fetchAndMergeClasses(): Promise< void > {
|
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const previewResponse = await
|
|
44
|
-
|
|
43
|
+
const [ previewResponse, frontendResponse ] = await Promise.all( [
|
|
44
|
+
apiClient.getStylesByIds( idsToFetch, 'preview' ),
|
|
45
|
+
apiClient.getStylesByIds( idsToFetch, 'frontend' ),
|
|
46
|
+
] );
|
|
45
47
|
const previewItems = styleDefinitionsMapWithoutNull( previewResponse.data.data );
|
|
46
48
|
const frontendItems = styleDefinitionsMapWithoutNull( frontendResponse.data.data );
|
|
47
49
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BREAKPOINTS_SCHEMA_FULL_URI, STYLE_SCHEMA_FULL_URI } from '@elementor/editor-canvas';
|
|
2
2
|
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
3
3
|
import { type Props, Schema } from '@elementor/editor-props';
|
|
4
4
|
import { type BreakpointId } from '@elementor/editor-responsive';
|
|
@@ -8,6 +8,7 @@ import { type Utils as IUtils } from '@elementor/editor-variables';
|
|
|
8
8
|
import { z } from '@elementor/schema';
|
|
9
9
|
|
|
10
10
|
import { globalClassesStylesProvider } from '../global-classes-styles-provider';
|
|
11
|
+
import { loadExistingClasses } from '../load-existing-classes';
|
|
11
12
|
import { saveGlobalClasses } from '../save-global-classes';
|
|
12
13
|
import { GLOBAL_CLASSES_URI } from './classes-resource';
|
|
13
14
|
|
|
@@ -23,21 +24,39 @@ const schema = {
|
|
|
23
24
|
globalClassName: z.string().optional().describe( 'Global class name (required for create)' ),
|
|
24
25
|
props: z.object( {
|
|
25
26
|
default: z
|
|
26
|
-
.record(
|
|
27
|
+
.record(
|
|
28
|
+
z.string().describe( 'The style property name' ),
|
|
29
|
+
z.any().describe( `The style PropValue, refer to [${ STYLE_SCHEMA_FULL_URI }] how to generate values` )
|
|
30
|
+
)
|
|
27
31
|
.describe(
|
|
28
|
-
'
|
|
32
|
+
'An object record containing style property names and their new values. MUST contain at least one property — empty objects are rejected.'
|
|
29
33
|
),
|
|
30
34
|
hover: z
|
|
31
|
-
.record(
|
|
32
|
-
|
|
35
|
+
.record(
|
|
36
|
+
z.string().describe( 'The style property name' ),
|
|
37
|
+
z.any().describe( `The style PropValue, refer to [${ STYLE_SCHEMA_FULL_URI }] how to generate values` )
|
|
38
|
+
)
|
|
39
|
+
.describe(
|
|
40
|
+
'An object record containing style property names and their new values to be set on the element. for :hover css state. optional'
|
|
41
|
+
)
|
|
33
42
|
.optional(),
|
|
34
43
|
focus: z
|
|
35
|
-
.record(
|
|
36
|
-
|
|
44
|
+
.record(
|
|
45
|
+
z.string().describe( 'The style property name' ),
|
|
46
|
+
z.any().describe( `The style PropValue, refer to [${ STYLE_SCHEMA_FULL_URI }] how to generate values` )
|
|
47
|
+
)
|
|
48
|
+
.describe(
|
|
49
|
+
'An object record containing style property names and their new values to be set on the element. for :focus css state. optional'
|
|
50
|
+
)
|
|
37
51
|
.optional(),
|
|
38
52
|
active: z
|
|
39
|
-
.record(
|
|
40
|
-
|
|
53
|
+
.record(
|
|
54
|
+
z.string().describe( 'The style property name' ),
|
|
55
|
+
z.any().describe( `The style PropValue, refer to [${ STYLE_SCHEMA_FULL_URI }] how to generate values` )
|
|
56
|
+
)
|
|
57
|
+
.describe(
|
|
58
|
+
'An object record containing style property names and their new values to be set on the element. for :active css state. optional'
|
|
59
|
+
)
|
|
41
60
|
.optional(),
|
|
42
61
|
} ),
|
|
43
62
|
breakpoint: z
|
|
@@ -105,13 +124,25 @@ const handler = async ( input: InputSchema ): Promise< OutputSchema > => {
|
|
|
105
124
|
} );
|
|
106
125
|
} );
|
|
107
126
|
|
|
127
|
+
if ( action !== 'delete' ) {
|
|
128
|
+
const hasAnyProps = Object.values( propsWithStates ).some(
|
|
129
|
+
( stateProps ) => Object.keys( stateProps ).length > 0
|
|
130
|
+
);
|
|
131
|
+
if ( ! hasAnyProps ) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
`Props must not be empty. Each prop must be a PropValue object from the style schema.\n\nExample: { "display": { "$$type": "string", "value": "flex" }, "flex-direction": { "$$type": "string", "value": "column" } }\n\n${ STYLE_SCHEMA_FULL_URI } to get the allowed values (look at the "value" enum in the schema response), then construct { "$$type": "string", "value": "<chosen value>" } for each property.\nAvailable Properties: ${ validProps.join(
|
|
134
|
+
', '
|
|
135
|
+
) }`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
108
140
|
if ( errors.length > 0 ) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
message: `Validation errors:\n${ errors.join( '\n' ) }\nAvailable Properties: ${ validProps.join(
|
|
141
|
+
throw new Error(
|
|
142
|
+
`Validation errors:\n${ errors.join( '\n' ) }\nAvailable Properties: ${ validProps.join(
|
|
112
143
|
', '
|
|
113
|
-
) }\nUpdate your input and try again
|
|
114
|
-
|
|
144
|
+
) }\nUpdate your input and try again.`
|
|
145
|
+
);
|
|
115
146
|
}
|
|
116
147
|
|
|
117
148
|
// TODO: see https://elementor.atlassian.net/browse/ED-22513 for better cross-module access
|
|
@@ -133,6 +164,17 @@ const handler = async ( input: InputSchema ): Promise< OutputSchema > => {
|
|
|
133
164
|
} as { status: 'error' | 'ok'; message?: string; classId?: string };
|
|
134
165
|
|
|
135
166
|
try {
|
|
167
|
+
if ( action === 'delete' ) {
|
|
168
|
+
const deleted = await attemptDelete( {
|
|
169
|
+
classId,
|
|
170
|
+
stylesProvider: globalClassesStylesProvider,
|
|
171
|
+
} );
|
|
172
|
+
if ( deleted ) {
|
|
173
|
+
return { status: 'ok', message: `deleted global class with ID ${ classId }` };
|
|
174
|
+
}
|
|
175
|
+
throw new Error( 'error deleting class' );
|
|
176
|
+
}
|
|
177
|
+
|
|
136
178
|
let currentAction = action;
|
|
137
179
|
for await ( const [ state, props ] of Object.entries( propsWithStates ) ) {
|
|
138
180
|
switch ( currentAction ) {
|
|
@@ -148,16 +190,13 @@ const handler = async ( input: InputSchema ): Promise< OutputSchema > => {
|
|
|
148
190
|
// NOTE: for multiple iterations as the state changes, the next execution would be update an existing class
|
|
149
191
|
currentAction = 'modify';
|
|
150
192
|
classId = newClassId;
|
|
193
|
+
result = {
|
|
194
|
+
status: 'ok',
|
|
195
|
+
message: `created global class with ID ${ newClassId }`,
|
|
196
|
+
};
|
|
197
|
+
} else {
|
|
198
|
+
throw new Error( 'error creating class' );
|
|
151
199
|
}
|
|
152
|
-
result = newClassId
|
|
153
|
-
? {
|
|
154
|
-
status: 'ok',
|
|
155
|
-
message: `created global class with ID ${ newClassId }`,
|
|
156
|
-
}
|
|
157
|
-
: {
|
|
158
|
-
status: 'error',
|
|
159
|
-
message: 'error creating class',
|
|
160
|
-
};
|
|
161
200
|
break;
|
|
162
201
|
case 'modify':
|
|
163
202
|
const updated = await attemptUpdate( {
|
|
@@ -167,24 +206,11 @@ const handler = async ( input: InputSchema ): Promise< OutputSchema > => {
|
|
|
167
206
|
breakpoint: breakpointValue as BreakpointId,
|
|
168
207
|
state: state as StyleDefinitionState,
|
|
169
208
|
} );
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
};
|
|
176
|
-
break;
|
|
177
|
-
case 'delete':
|
|
178
|
-
const deleted = await attemptDelete( {
|
|
179
|
-
classId,
|
|
180
|
-
stylesProvider: globalClassesStylesProvider,
|
|
181
|
-
} );
|
|
182
|
-
result = deleted
|
|
183
|
-
? { status: 'ok', message: `deleted global class with ID ${ classId }` }
|
|
184
|
-
: {
|
|
185
|
-
status: 'error',
|
|
186
|
-
message: 'error deleting class',
|
|
187
|
-
};
|
|
209
|
+
if ( updated ) {
|
|
210
|
+
result = { status: 'ok', classId };
|
|
211
|
+
} else {
|
|
212
|
+
throw new Error( 'error modifying class' );
|
|
213
|
+
}
|
|
188
214
|
break;
|
|
189
215
|
default:
|
|
190
216
|
throw new Error( `Unsupported action ${ action }` );
|
|
@@ -206,10 +232,21 @@ export const initManageGlobalClasses = ( reg: MCPRegistryEntry ) => {
|
|
|
206
232
|
name: 'manage-global-classes',
|
|
207
233
|
requiredResources: [
|
|
208
234
|
{ uri: GLOBAL_CLASSES_URI, description: 'Global classes list' },
|
|
209
|
-
{ uri:
|
|
210
|
-
{ uri:
|
|
235
|
+
{ uri: STYLE_SCHEMA_FULL_URI, description: 'Style schema resources' },
|
|
236
|
+
{ uri: BREAKPOINTS_SCHEMA_FULL_URI, description: 'Breakpoints list' },
|
|
211
237
|
],
|
|
212
|
-
description: `Create or modify global classes for reusable design-system styling. Class names must reflect purpose (e.g. heading-primary, button-cta). Create classes BEFORE
|
|
238
|
+
description: `Create or modify global classes for reusable design-system styling. Class names must reflect purpose (e.g. heading-primary, button-cta). Create classes BEFORE applying them. Do NOT create classes for one-off styles.
|
|
239
|
+
|
|
240
|
+
IMPORTANT: props must contain actual CSS property values — never pass empty objects.
|
|
241
|
+
Fetch ${ STYLE_SCHEMA_FULL_URI } to get the allowed values for each property, then use them to build the props object.
|
|
242
|
+
|
|
243
|
+
Example — creating a flex column class:
|
|
244
|
+
props.default = {
|
|
245
|
+
"display": { "$$type": "string", "value": "flex" },
|
|
246
|
+
"flex-direction": { "$$type": "string", "value": "column" }
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
The style schema returns a JSON Schema. Extract the "value" enum to pick the right value, then construct { "$$type": "string", "value": "<picked value>" }.`,
|
|
213
250
|
schema,
|
|
214
251
|
outputSchema,
|
|
215
252
|
handler,
|
|
@@ -249,7 +286,7 @@ async function attemptCreate( opts: Opts ) {
|
|
|
249
286
|
return newClassId;
|
|
250
287
|
} catch {
|
|
251
288
|
deleteClass( newClassId );
|
|
252
|
-
|
|
289
|
+
throw new Error( 'error creating class' );
|
|
253
290
|
}
|
|
254
291
|
}
|
|
255
292
|
|
|
@@ -262,6 +299,7 @@ async function attemptUpdate( opts: Opts ) {
|
|
|
262
299
|
if ( ! updateProps || ! update ) {
|
|
263
300
|
throw new Error( 'User is unable to update global classes' );
|
|
264
301
|
}
|
|
302
|
+
await loadExistingClasses( [ classId ] );
|
|
265
303
|
const snapshot = structuredClone( stylesProvider.actions.all() );
|
|
266
304
|
try {
|
|
267
305
|
updateProps( {
|
|
@@ -269,7 +307,7 @@ async function attemptUpdate( opts: Opts ) {
|
|
|
269
307
|
props,
|
|
270
308
|
meta: {
|
|
271
309
|
breakpoint,
|
|
272
|
-
state,
|
|
310
|
+
state: ( state as string ) === 'default' ? null : state,
|
|
273
311
|
},
|
|
274
312
|
} );
|
|
275
313
|
await saveGlobalClasses( { context: 'frontend' } );
|
|
@@ -282,7 +320,7 @@ async function attemptUpdate( opts: Opts ) {
|
|
|
282
320
|
} );
|
|
283
321
|
} );
|
|
284
322
|
await saveGlobalClasses( { context: 'frontend' } );
|
|
285
|
-
|
|
323
|
+
throw new Error( 'error updating class' );
|
|
286
324
|
}
|
|
287
325
|
}
|
|
288
326
|
|
|
@@ -300,11 +338,7 @@ async function attemptDelete( opts: Pick< Opts, 'classId' | 'stylesProvider' > )
|
|
|
300
338
|
if ( ! targetClass ) {
|
|
301
339
|
throw new Error( `Class with ID "${ classId }" not found` );
|
|
302
340
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return true;
|
|
307
|
-
} catch {
|
|
308
|
-
return false;
|
|
309
|
-
}
|
|
341
|
+
deleteClass( classId );
|
|
342
|
+
await saveGlobalClasses( { context: 'frontend' } );
|
|
343
|
+
return true;
|
|
310
344
|
}
|