@elementor/editor-styles-repository 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,22 @@
1
1
 
2
- > @elementor/editor-styles-repository@0.5.0 build
2
+ > @elementor/editor-styles-repository@0.7.0 build
3
3
  > tsup --config=../../tsup.build.ts
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: ../../../tsconfig.json
7
- CLI tsup v8.3.5
7
+ CLI tsup v8.4.0
8
8
  CLI Using tsup config: /home/runner/work/elementor-packages/elementor-packages/tsup.build.ts
9
9
  CLI Target: esnext
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
- CJS dist/index.js 4.69 KB
14
- CJS dist/index.js.map 8.12 KB
15
- CJS ⚡️ Build success in 55ms
16
- ESM dist/index.mjs 3.31 KB
17
- ESM dist/index.mjs.map 8.04 KB
18
- ESM ⚡️ Build success in 55ms
13
+ CJS dist/index.js 6.15 KB
14
+ CJS dist/index.js.map 10.97 KB
15
+ CJS ⚡️ Build success in 71ms
16
+ ESM dist/index.mjs 4.71 KB
17
+ ESM dist/index.mjs.map 10.88 KB
18
+ ESM ⚡️ Build success in 80ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 4346ms
21
- DTS dist/index.d.mts 1.84 KB
22
- DTS dist/index.d.ts 1.84 KB
20
+ DTS ⚡️ Build success in 4771ms
21
+ DTS dist/index.d.mts 2.15 KB
22
+ DTS dist/index.d.ts 2.15 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # @elementor/editor-styles-repository
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 188069d: Added global classes reorder support.
8
+ - 4ed562a: Support renaming label in classes manager.
9
+ - ebd9676: Added delete global class action.
10
+
11
+ ### Patch Changes
12
+
13
+ - e6c904a: Make global classes state changes synchronous
14
+ - efdadea: Create validation utils in style repository
15
+ - da38fa9: Remove unused exports and add missing dependencies.
16
+ - ffad70a: Fix base styles rendring
17
+ - ad6fde0: Support history actions in style changes
18
+ - Updated dependencies [c9133d7]
19
+ - Updated dependencies [86863c1]
20
+ - Updated dependencies [e441663]
21
+ - Updated dependencies [da38fa9]
22
+ - Updated dependencies [9ca4eab]
23
+ - Updated dependencies [15c964f]
24
+ - Updated dependencies [ad6fde0]
25
+ - Updated dependencies [b8e2a85]
26
+ - @elementor/editor-props@0.9.0
27
+ - @elementor/editor-elements@0.5.2
28
+ - @elementor/editor-v1-adapters@0.10.0
29
+ - @elementor/utils@0.3.1
30
+ - @elementor/editor-styles@0.5.5
31
+
32
+ ## 0.6.0
33
+
34
+ ### Minor Changes
35
+
36
+ - 19b0381: Change styles repository API
37
+
38
+ ### Patch Changes
39
+
40
+ - d61b1bc: Added a new event to update the elements styles repository + organized all events in a central location
41
+ - b34f498: Fix global class styles not updating
42
+ - Updated dependencies [d61b1bc]
43
+ - Updated dependencies [a8b60c9]
44
+ - Updated dependencies [b34f498]
45
+ - @elementor/editor-elements@0.5.1
46
+ - @elementor/editor-v1-adapters@0.9.1
47
+ - @elementor/editor-styles@0.5.4
48
+
3
49
  ## 0.5.0
4
50
 
5
51
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -1,40 +1,52 @@
1
+ import { Props } from '@elementor/editor-props';
1
2
  import * as _elementor_editor_styles from '@elementor/editor-styles';
2
- import { StyleDefinition } from '@elementor/editor-styles';
3
+ import { StyleDefinition, StyleDefinitionID, StyleDefinitionVariant } from '@elementor/editor-styles';
3
4
 
4
5
  type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
5
- type GetActionPayload = Record<string, unknown>;
6
- type CreateActionPayload = MakeOptional<StyleDefinition, 'id' | 'type' | 'variants'>;
7
6
  type UpdateActionPayload = MakeOptional<StyleDefinition, 'label' | 'variants' | 'type'>;
7
+ type UpdatePropsActionPayload = {
8
+ id: StyleDefinitionID;
9
+ meta: StyleDefinitionVariant['meta'];
10
+ props: Props;
11
+ };
12
+ type Meta = Record<string, unknown>;
8
13
  type StylesProvider = {
9
14
  key: string;
10
15
  priority: number;
11
16
  actions: {
12
- get: (meta?: GetActionPayload) => StyleDefinition[];
13
- create?: (data: CreateActionPayload) => Promise<StyleDefinition>;
14
- update?: (data: UpdateActionPayload) => Promise<StyleDefinition>;
17
+ get: (meta?: Meta) => StyleDefinition[];
18
+ getById: (id: StyleDefinitionID, meta?: Meta) => StyleDefinition | null;
19
+ create?: (label: StyleDefinition['label']) => StyleDefinitionID;
20
+ delete?: (id: StyleDefinitionID) => void;
21
+ setOrder?: (order: StyleDefinitionID[]) => void;
22
+ update?: (data: UpdateActionPayload) => void;
23
+ updateProps?: (args: UpdatePropsActionPayload, meta?: Meta) => void;
15
24
  };
16
25
  subscribe: (callback: () => void) => () => void;
17
26
  labels?: {
18
27
  singular: string;
19
28
  plural: string;
20
29
  };
30
+ reservedLabel?: string;
21
31
  };
22
32
 
23
33
  declare const stylesRepository: {
24
- all: (meta?: GetActionPayload) => _elementor_editor_styles.StyleDefinition[];
25
- allByProvider: (meta?: GetActionPayload) => (readonly [StylesProvider, _elementor_editor_styles.StyleDefinition[]])[];
34
+ all: (meta?: Meta) => _elementor_editor_styles.StyleDefinition[];
26
35
  register: (provider: StylesProvider) => void;
27
36
  subscribe: (cb: () => void) => () => void;
28
37
  getProviders: () => StylesProvider[];
29
38
  getProviderByKey: (key: string) => StylesProvider | undefined;
39
+ isLabelExist: (newLabel: string) => boolean;
40
+ isLabelValid: (newLabel: string) => boolean;
30
41
  };
31
42
 
32
- declare function useAllStylesByProvider(meta?: GetActionPayload): (readonly [StylesProvider, _elementor_editor_styles.StyleDefinition[]])[];
43
+ declare function useProviders(): StylesProvider[];
33
44
 
34
45
  type CreateAction = Required<StylesProvider['actions']>['create'];
35
46
  type CreateTuple = [StylesProvider, CreateAction];
36
47
  declare function useCreateActionsByProvider(): CreateTuple[];
37
48
 
38
49
  declare const ELEMENTS_STYLES_PROVIDER_KEY = "elements";
50
+ declare const LOCAL_STYLES_RESERVED_LABEL = "local";
39
51
 
40
- export { type CreateActionPayload, ELEMENTS_STYLES_PROVIDER_KEY, type GetActionPayload, type StylesProvider, type UpdateActionPayload, stylesRepository, useAllStylesByProvider, useCreateActionsByProvider };
52
+ export { ELEMENTS_STYLES_PROVIDER_KEY, LOCAL_STYLES_RESERVED_LABEL, type Meta, type StylesProvider, type UpdateActionPayload, type UpdatePropsActionPayload, stylesRepository, useCreateActionsByProvider, useProviders };
package/dist/index.d.ts CHANGED
@@ -1,40 +1,52 @@
1
+ import { Props } from '@elementor/editor-props';
1
2
  import * as _elementor_editor_styles from '@elementor/editor-styles';
2
- import { StyleDefinition } from '@elementor/editor-styles';
3
+ import { StyleDefinition, StyleDefinitionID, StyleDefinitionVariant } from '@elementor/editor-styles';
3
4
 
4
5
  type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
5
- type GetActionPayload = Record<string, unknown>;
6
- type CreateActionPayload = MakeOptional<StyleDefinition, 'id' | 'type' | 'variants'>;
7
6
  type UpdateActionPayload = MakeOptional<StyleDefinition, 'label' | 'variants' | 'type'>;
7
+ type UpdatePropsActionPayload = {
8
+ id: StyleDefinitionID;
9
+ meta: StyleDefinitionVariant['meta'];
10
+ props: Props;
11
+ };
12
+ type Meta = Record<string, unknown>;
8
13
  type StylesProvider = {
9
14
  key: string;
10
15
  priority: number;
11
16
  actions: {
12
- get: (meta?: GetActionPayload) => StyleDefinition[];
13
- create?: (data: CreateActionPayload) => Promise<StyleDefinition>;
14
- update?: (data: UpdateActionPayload) => Promise<StyleDefinition>;
17
+ get: (meta?: Meta) => StyleDefinition[];
18
+ getById: (id: StyleDefinitionID, meta?: Meta) => StyleDefinition | null;
19
+ create?: (label: StyleDefinition['label']) => StyleDefinitionID;
20
+ delete?: (id: StyleDefinitionID) => void;
21
+ setOrder?: (order: StyleDefinitionID[]) => void;
22
+ update?: (data: UpdateActionPayload) => void;
23
+ updateProps?: (args: UpdatePropsActionPayload, meta?: Meta) => void;
15
24
  };
16
25
  subscribe: (callback: () => void) => () => void;
17
26
  labels?: {
18
27
  singular: string;
19
28
  plural: string;
20
29
  };
30
+ reservedLabel?: string;
21
31
  };
22
32
 
23
33
  declare const stylesRepository: {
24
- all: (meta?: GetActionPayload) => _elementor_editor_styles.StyleDefinition[];
25
- allByProvider: (meta?: GetActionPayload) => (readonly [StylesProvider, _elementor_editor_styles.StyleDefinition[]])[];
34
+ all: (meta?: Meta) => _elementor_editor_styles.StyleDefinition[];
26
35
  register: (provider: StylesProvider) => void;
27
36
  subscribe: (cb: () => void) => () => void;
28
37
  getProviders: () => StylesProvider[];
29
38
  getProviderByKey: (key: string) => StylesProvider | undefined;
39
+ isLabelExist: (newLabel: string) => boolean;
40
+ isLabelValid: (newLabel: string) => boolean;
30
41
  };
31
42
 
32
- declare function useAllStylesByProvider(meta?: GetActionPayload): (readonly [StylesProvider, _elementor_editor_styles.StyleDefinition[]])[];
43
+ declare function useProviders(): StylesProvider[];
33
44
 
34
45
  type CreateAction = Required<StylesProvider['actions']>['create'];
35
46
  type CreateTuple = [StylesProvider, CreateAction];
36
47
  declare function useCreateActionsByProvider(): CreateTuple[];
37
48
 
38
49
  declare const ELEMENTS_STYLES_PROVIDER_KEY = "elements";
50
+ declare const LOCAL_STYLES_RESERVED_LABEL = "local";
39
51
 
40
- export { type CreateActionPayload, ELEMENTS_STYLES_PROVIDER_KEY, type GetActionPayload, type StylesProvider, type UpdateActionPayload, stylesRepository, useAllStylesByProvider, useCreateActionsByProvider };
52
+ export { ELEMENTS_STYLES_PROVIDER_KEY, LOCAL_STYLES_RESERVED_LABEL, type Meta, type StylesProvider, type UpdateActionPayload, type UpdatePropsActionPayload, stylesRepository, useCreateActionsByProvider, useProviders };
package/dist/index.js CHANGED
@@ -21,13 +21,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ELEMENTS_STYLES_PROVIDER_KEY: () => ELEMENTS_STYLES_PROVIDER_KEY,
24
+ LOCAL_STYLES_RESERVED_LABEL: () => LOCAL_STYLES_RESERVED_LABEL,
24
25
  stylesRepository: () => stylesRepository,
25
- useAllStylesByProvider: () => useAllStylesByProvider,
26
- useCreateActionsByProvider: () => useCreateActionsByProvider
26
+ useCreateActionsByProvider: () => useCreateActionsByProvider,
27
+ useProviders: () => useProviders
27
28
  });
28
29
  module.exports = __toCommonJS(index_exports);
29
30
 
30
31
  // src/utils/create-styles-repository.ts
32
+ var VALID_SELECTOR_REGEX = /^[a-zA-Z0-9_-]+$/;
31
33
  var createStylesRepository = () => {
32
34
  const providers = [];
33
35
  const getProviders = () => {
@@ -36,9 +38,6 @@ var createStylesRepository = () => {
36
38
  const register = (provider) => {
37
39
  providers.push(provider);
38
40
  };
39
- const allByProvider = (meta = {}) => {
40
- return getProviders().map((provider) => [provider, provider.actions.get(meta)]);
41
- };
42
41
  const all = (meta = {}) => {
43
42
  return getProviders().flatMap((provider) => provider.actions.get(meta));
44
43
  };
@@ -53,25 +52,38 @@ var createStylesRepository = () => {
53
52
  const getProviderByKey = (key) => {
54
53
  return providers.find((provider) => provider.key === key);
55
54
  };
55
+ const isLabelExist = (newLabel) => {
56
+ const classes = all();
57
+ const reservedLabels = providers.map(({ reservedLabel }) => reservedLabel).filter(Boolean);
58
+ if (reservedLabels.includes(newLabel)) {
59
+ return true;
60
+ }
61
+ if (!classes?.length) {
62
+ return false;
63
+ }
64
+ return classes.some(({ label }) => label.toLowerCase() === newLabel.toLowerCase());
65
+ };
66
+ const isLabelValid = (newLabel) => VALID_SELECTOR_REGEX.test(newLabel);
56
67
  return {
57
68
  all,
58
- allByProvider,
59
69
  register,
60
70
  subscribe,
61
71
  getProviders,
62
- getProviderByKey
72
+ getProviderByKey,
73
+ isLabelExist,
74
+ isLabelValid
63
75
  };
64
76
  };
65
77
 
66
78
  // src/styles-repository.ts
67
79
  var stylesRepository = createStylesRepository();
68
80
 
69
- // src/hooks/use-all-styles-by-provider.ts
81
+ // src/hooks/use-providers.ts
70
82
  var import_react = require("react");
71
- function useAllStylesByProvider(meta = {}) {
83
+ function useProviders() {
72
84
  const [, rerender] = (0, import_react.useReducer)((prev) => !prev, false);
73
85
  (0, import_react.useEffect)(() => stylesRepository.subscribe(rerender), []);
74
- return stylesRepository.allByProvider(meta);
86
+ return stylesRepository.getProviders();
75
87
  }
76
88
 
77
89
  // src/hooks/use-create-actions-by-provider.ts
@@ -90,37 +102,69 @@ function useCreateActionsByProvider() {
90
102
  // src/elements-styles-provider.ts
91
103
  var import_editor_elements = require("@elementor/editor-elements");
92
104
  var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
105
+
106
+ // src/errors.ts
107
+ var import_utils = require("@elementor/utils");
108
+ var InvalidElementsStyleProviderMetaError = (0, import_utils.createError)({
109
+ code: "invalid_elements_style_provider_meta",
110
+ message: "Invalid elements style provider meta."
111
+ });
112
+
113
+ // src/elements-styles-provider.ts
93
114
  var ELEMENTS_STYLES_PROVIDER_KEY = "elements";
115
+ var LOCAL_STYLES_RESERVED_LABEL = "local";
94
116
  var elementsStylesProvider = {
95
117
  key: ELEMENTS_STYLES_PROVIDER_KEY,
96
118
  priority: 50,
97
119
  actions: {
98
120
  get: (meta = {}) => {
99
121
  let elements = (0, import_editor_elements.getElements)();
100
- if ("elementId" in meta && meta.elementId) {
122
+ if (isValidElementsMeta(meta)) {
101
123
  elements = elements.filter((element) => element.id === meta.elementId);
102
124
  }
103
125
  return elements.flatMap((element) => Object.values(element.model.get("styles") ?? {}));
126
+ },
127
+ getById: (id, meta = {}) => {
128
+ if (!isValidElementsMeta(meta)) {
129
+ throw new InvalidElementsStyleProviderMetaError({ context: { meta } });
130
+ }
131
+ const styles = (0, import_editor_elements.getElementStyles)(meta.elementId) ?? {};
132
+ return styles[id] ?? null;
133
+ },
134
+ updateProps: (args, meta = {}) => {
135
+ if (!isValidElementsMeta(meta)) {
136
+ throw new InvalidElementsStyleProviderMetaError({ context: { meta } });
137
+ }
138
+ (0, import_editor_elements.updateElementStyle)({
139
+ elementId: meta.elementId,
140
+ styleId: args.id,
141
+ meta: args.meta,
142
+ props: args.props
143
+ });
104
144
  }
105
145
  },
106
- subscribe: (cb) => {
107
- return (0, import_editor_v1_adapters.__privateListenTo)(
108
- [(0, import_editor_v1_adapters.commandEndEvent)("editor/documents/attach-preview"), (0, import_editor_v1_adapters.windowEvent)(import_editor_elements.ELEMENT_STYLE_CHANGE_EVENT)],
109
- cb
110
- );
111
- }
146
+ subscribe: (cb) => (0, import_editor_v1_adapters.__privateListenTo)(import_editor_elements.styleRerenderEvents, cb),
147
+ reservedLabel: LOCAL_STYLES_RESERVED_LABEL
112
148
  };
149
+ function isValidElementsMeta(meta) {
150
+ return "elementId" in meta && typeof meta.elementId === "string" && !!meta.elementId;
151
+ }
113
152
 
114
153
  // src/element-base-styles-provider.ts
115
154
  var import_editor_elements2 = require("@elementor/editor-elements");
116
155
  var ELEMENTS_BASE_STYLES_PROVIDER_KEY = "element-base-styles";
117
156
  var elementBaseStylesProvider = {
118
157
  key: ELEMENTS_BASE_STYLES_PROVIDER_KEY,
119
- priority: 60,
158
+ priority: 10,
120
159
  actions: {
121
- get: () => {
160
+ get() {
122
161
  const widgetsCache = (0, import_editor_elements2.getWidgetsCache)();
123
- return Object.values(widgetsCache ?? {}).flatMap((widget) => widget.base_styles ?? []);
162
+ return Object.values(widgetsCache ?? {}).flatMap(
163
+ (widget) => Object.values(widget.base_styles ?? {})
164
+ );
165
+ },
166
+ getById(id) {
167
+ return this.get().find((style) => style.id === id) ?? null;
124
168
  }
125
169
  },
126
170
  subscribe: () => {
@@ -140,8 +184,9 @@ init();
140
184
  // Annotate the CommonJS export names for ESM import in node:
141
185
  0 && (module.exports = {
142
186
  ELEMENTS_STYLES_PROVIDER_KEY,
187
+ LOCAL_STYLES_RESERVED_LABEL,
143
188
  stylesRepository,
144
- useAllStylesByProvider,
145
- useCreateActionsByProvider
189
+ useCreateActionsByProvider,
190
+ useProviders
146
191
  });
147
192
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/create-styles-repository.ts","../src/styles-repository.ts","../src/hooks/use-all-styles-by-provider.ts","../src/hooks/use-create-actions-by-provider.ts","../src/elements-styles-provider.ts","../src/element-base-styles-provider.ts","../src/init.ts"],"sourcesContent":["export {\n\ttype StylesProvider,\n\ttype CreateActionPayload,\n\ttype GetActionPayload,\n\ttype UpdateActionPayload,\n} from './utils/create-styles-repository';\n\nexport { stylesRepository } from './styles-repository';\nexport { useAllStylesByProvider } from './hooks/use-all-styles-by-provider';\nexport { useCreateActionsByProvider } from './hooks/use-create-actions-by-provider';\n\nexport { ELEMENTS_STYLES_PROVIDER_KEY } from './elements-styles-provider';\n\nimport { init } from './init';\n\ninit();\n","import { type StyleDefinition } from '@elementor/editor-styles';\n\nexport type MakeOptional< T, K extends keyof T > = Omit< T, K > & Partial< T >;\n\nexport type GetActionPayload = Record< string, unknown >;\nexport type CreateActionPayload = MakeOptional< StyleDefinition, 'id' | 'type' | 'variants' >;\nexport type UpdateActionPayload = MakeOptional< StyleDefinition, 'label' | 'variants' | 'type' >;\n\nexport type StylesProvider = {\n\tkey: string;\n\tpriority: number;\n\tactions: {\n\t\tget: ( meta?: GetActionPayload ) => StyleDefinition[];\n\t\tcreate?: ( data: CreateActionPayload ) => Promise< StyleDefinition >;\n\t\tupdate?: ( data: UpdateActionPayload ) => Promise< StyleDefinition >;\n\t};\n\tsubscribe: ( callback: () => void ) => () => void;\n\tlabels?: {\n\t\tsingular: string;\n\t\tplural: string;\n\t};\n};\n\nexport const createStylesRepository = () => {\n\tconst providers: StylesProvider[] = [];\n\n\tconst getProviders = () => {\n\t\treturn providers.slice( 0 ).sort( ( a, b ) => ( a.priority > b.priority ? -1 : 1 ) );\n\t};\n\n\tconst register = ( provider: StylesProvider ) => {\n\t\tproviders.push( provider );\n\t};\n\n\tconst allByProvider = ( meta: GetActionPayload = {} ) => {\n\t\treturn getProviders().map( ( provider ) => [ provider, provider.actions.get( meta ) ] as const );\n\t};\n\n\tconst all = ( meta: GetActionPayload = {} ) => {\n\t\treturn getProviders().flatMap( ( provider ) => provider.actions.get( meta ) );\n\t};\n\n\tconst subscribe = ( cb: () => void ) => {\n\t\tconst unsubscribes = providers.map( ( provider ) => {\n\t\t\treturn provider.subscribe( cb );\n\t\t} );\n\n\t\treturn () => {\n\t\t\tunsubscribes.forEach( ( unsubscribe ) => unsubscribe() );\n\t\t};\n\t};\n\n\tconst getProviderByKey = ( key: string ) => {\n\t\treturn providers.find( ( provider ) => provider.key === key );\n\t};\n\n\treturn {\n\t\tall,\n\t\tallByProvider,\n\t\tregister,\n\t\tsubscribe,\n\t\tgetProviders,\n\t\tgetProviderByKey,\n\t};\n};\n","import { createStylesRepository } from './utils/create-styles-repository';\n\nexport const stylesRepository = createStylesRepository();\n","import { useEffect, useReducer } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\nimport { type GetActionPayload } from '../utils/create-styles-repository';\n\nexport function useAllStylesByProvider( meta: GetActionPayload = {} ) {\n\tconst [ , rerender ] = useReducer( ( prev ) => ! prev, false );\n\n\tuseEffect( () => stylesRepository.subscribe( rerender ), [] );\n\n\treturn stylesRepository.allByProvider( meta );\n}\n","import { useMemo } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\nimport { type StylesProvider } from '../utils/create-styles-repository';\n\ntype CreateAction = Required< StylesProvider[ 'actions' ] >[ 'create' ];\ntype CreateTuple = [ StylesProvider, CreateAction ];\n\nexport function useCreateActionsByProvider() {\n\treturn useMemo( () => {\n\t\treturn stylesRepository\n\t\t\t.getProviders()\n\t\t\t.map< CreateTuple | null >( ( provider ) => {\n\t\t\t\tif ( ! provider.actions.create ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn [ provider, provider.actions.create ];\n\t\t\t} )\n\t\t\t.filter( ( item ) => !! item );\n\t}, [] );\n}\n","import { ELEMENT_STYLE_CHANGE_EVENT, getElements } from '@elementor/editor-elements';\nimport { __privateListenTo as listenTo, commandEndEvent, windowEvent } from '@elementor/editor-v1-adapters';\n\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nexport const ELEMENTS_STYLES_PROVIDER_KEY = 'elements';\n\nexport const elementsStylesProvider: StylesProvider = {\n\tkey: ELEMENTS_STYLES_PROVIDER_KEY,\n\tpriority: 50,\n\tactions: {\n\t\tget: ( meta = {} ) => {\n\t\t\tlet elements = getElements();\n\n\t\t\tif ( 'elementId' in meta && meta.elementId ) {\n\t\t\t\telements = elements.filter( ( element ) => element.id === meta.elementId );\n\t\t\t}\n\n\t\t\treturn elements.flatMap( ( element ) => Object.values( element.model.get( 'styles' ) ?? {} ) );\n\t\t},\n\t},\n\tsubscribe: ( cb ) => {\n\t\treturn listenTo(\n\t\t\t[ commandEndEvent( 'editor/documents/attach-preview' ), windowEvent( ELEMENT_STYLE_CHANGE_EVENT ) ],\n\t\t\tcb\n\t\t);\n\t},\n};\n","import { getWidgetsCache } from '@elementor/editor-elements';\n\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nconst ELEMENTS_BASE_STYLES_PROVIDER_KEY = 'element-base-styles';\n\nexport const elementBaseStylesProvider: StylesProvider = {\n\tkey: ELEMENTS_BASE_STYLES_PROVIDER_KEY,\n\tpriority: 60,\n\tactions: {\n\t\tget: () => {\n\t\t\tconst widgetsCache = getWidgetsCache();\n\n\t\t\treturn Object.values( widgetsCache ?? {} ).flatMap( ( widget ) => widget.base_styles ?? [] );\n\t\t},\n\t},\n\tsubscribe: () => {\n\t\treturn () => {};\n\t},\n};\n","import { elementBaseStylesProvider } from './element-base-styles-provider';\nimport { elementsStylesProvider } from './elements-styles-provider';\nimport { stylesRepository } from './styles-repository';\n\nexport function init() {\n\tstylesRepository.register( elementsStylesProvider );\n\tstylesRepository.register( elementBaseStylesProvider );\n}\n"],"mappings":"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","names":["import_react","listenTo","import_editor_elements"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/create-styles-repository.ts","../src/styles-repository.ts","../src/hooks/use-providers.ts","../src/hooks/use-create-actions-by-provider.ts","../src/elements-styles-provider.ts","../src/errors.ts","../src/element-base-styles-provider.ts","../src/init.ts"],"sourcesContent":["export {\n\ttype StylesProvider,\n\ttype UpdateActionPayload,\n\ttype Meta,\n\ttype UpdatePropsActionPayload,\n} from './utils/create-styles-repository';\n\nexport { stylesRepository } from './styles-repository';\nexport { useProviders } from './hooks/use-providers';\nexport { useCreateActionsByProvider } from './hooks/use-create-actions-by-provider';\n\nexport { ELEMENTS_STYLES_PROVIDER_KEY, LOCAL_STYLES_RESERVED_LABEL } from './elements-styles-provider';\n\nimport { init } from './init';\n\ninit();\n","import { type Props } from '@elementor/editor-props';\nimport { type StyleDefinition, type StyleDefinitionID, type StyleDefinitionVariant } from '@elementor/editor-styles';\n\ntype MakeOptional< T, K extends keyof T > = Omit< T, K > & Partial< T >;\n\nexport type UpdateActionPayload = MakeOptional< StyleDefinition, 'label' | 'variants' | 'type' >;\n\nexport type UpdatePropsActionPayload = {\n\tid: StyleDefinitionID;\n\tmeta: StyleDefinitionVariant[ 'meta' ];\n\tprops: Props;\n};\n\nexport type Meta = Record< string, unknown >;\n\nexport type StylesProvider = {\n\tkey: string;\n\tpriority: number;\n\tactions: {\n\t\tget: ( meta?: Meta ) => StyleDefinition[];\n\t\tgetById: ( id: StyleDefinitionID, meta?: Meta ) => StyleDefinition | null;\n\t\tcreate?: ( label: StyleDefinition[ 'label' ] ) => StyleDefinitionID;\n\t\tdelete?: ( id: StyleDefinitionID ) => void;\n\t\tsetOrder?: ( order: StyleDefinitionID[] ) => void;\n\t\tupdate?: ( data: UpdateActionPayload ) => void;\n\t\tupdateProps?: ( args: UpdatePropsActionPayload, meta?: Meta ) => void;\n\t};\n\tsubscribe: ( callback: () => void ) => () => void;\n\tlabels?: {\n\t\tsingular: string;\n\t\tplural: string;\n\t};\n\treservedLabel?: string;\n};\n\nconst VALID_SELECTOR_REGEX = /^[a-zA-Z0-9_-]+$/;\n\nexport const createStylesRepository = () => {\n\tconst providers: StylesProvider[] = [];\n\n\tconst getProviders = () => {\n\t\treturn providers.slice( 0 ).sort( ( a, b ) => ( a.priority > b.priority ? -1 : 1 ) );\n\t};\n\n\tconst register = ( provider: StylesProvider ) => {\n\t\tproviders.push( provider );\n\t};\n\n\tconst all = ( meta: Meta = {} ) => {\n\t\treturn getProviders().flatMap( ( provider ) => provider.actions.get( meta ) );\n\t};\n\n\tconst subscribe = ( cb: () => void ) => {\n\t\tconst unsubscribes = providers.map( ( provider ) => {\n\t\t\treturn provider.subscribe( cb );\n\t\t} );\n\n\t\treturn () => {\n\t\t\tunsubscribes.forEach( ( unsubscribe ) => unsubscribe() );\n\t\t};\n\t};\n\n\tconst getProviderByKey = ( key: string ) => {\n\t\treturn providers.find( ( provider ) => provider.key === key );\n\t};\n\n\tconst isLabelExist = ( newLabel: string ) => {\n\t\tconst classes = all();\n\t\tconst reservedLabels = providers.map( ( { reservedLabel } ) => reservedLabel ).filter( Boolean );\n\n\t\tif ( reservedLabels.includes( newLabel ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( ! classes?.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn classes.some( ( { label } ) => label.toLowerCase() === newLabel.toLowerCase() );\n\t};\n\n\tconst isLabelValid = ( newLabel: string ) => VALID_SELECTOR_REGEX.test( newLabel );\n\n\treturn {\n\t\tall,\n\t\tregister,\n\t\tsubscribe,\n\t\tgetProviders,\n\t\tgetProviderByKey,\n\t\tisLabelExist,\n\t\tisLabelValid,\n\t};\n};\n","import { createStylesRepository } from './utils/create-styles-repository';\n\nexport const stylesRepository = createStylesRepository();\n","import { useEffect, useReducer } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\n\nexport function useProviders() {\n\tconst [ , rerender ] = useReducer( ( prev ) => ! prev, false );\n\n\tuseEffect( () => stylesRepository.subscribe( rerender ), [] );\n\n\treturn stylesRepository.getProviders();\n}\n","import { useMemo } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\nimport { type StylesProvider } from '../utils/create-styles-repository';\n\ntype CreateAction = Required< StylesProvider[ 'actions' ] >[ 'create' ];\ntype CreateTuple = [ StylesProvider, CreateAction ];\n\nexport function useCreateActionsByProvider() {\n\treturn useMemo( () => {\n\t\treturn stylesRepository\n\t\t\t.getProviders()\n\t\t\t.map< CreateTuple | null >( ( provider ) => {\n\t\t\t\tif ( ! provider.actions.create ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn [ provider, provider.actions.create ];\n\t\t\t} )\n\t\t\t.filter( ( item ) => !! item );\n\t}, [] );\n}\n","import { getElements, getElementStyles, styleRerenderEvents, updateElementStyle } from '@elementor/editor-elements';\nimport { __privateListenTo as listenTo } from '@elementor/editor-v1-adapters';\n\nimport { InvalidElementsStyleProviderMetaError } from './errors';\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nexport const ELEMENTS_STYLES_PROVIDER_KEY = 'elements';\nexport const LOCAL_STYLES_RESERVED_LABEL = 'local';\n\nexport const elementsStylesProvider = {\n\tkey: ELEMENTS_STYLES_PROVIDER_KEY,\n\tpriority: 50,\n\tactions: {\n\t\tget: ( meta = {} ) => {\n\t\t\tlet elements = getElements();\n\n\t\t\tif ( isValidElementsMeta( meta ) ) {\n\t\t\t\telements = elements.filter( ( element ) => element.id === meta.elementId );\n\t\t\t}\n\n\t\t\treturn elements.flatMap( ( element ) => Object.values( element.model.get( 'styles' ) ?? {} ) );\n\t\t},\n\n\t\tgetById: ( id, meta = {} ) => {\n\t\t\tif ( ! isValidElementsMeta( meta ) ) {\n\t\t\t\tthrow new InvalidElementsStyleProviderMetaError( { context: { meta } } );\n\t\t\t}\n\n\t\t\tconst styles = getElementStyles( meta.elementId ) ?? {};\n\n\t\t\treturn styles[ id ] ?? null;\n\t\t},\n\n\t\tupdateProps: ( args, meta = {} ) => {\n\t\t\tif ( ! isValidElementsMeta( meta ) ) {\n\t\t\t\tthrow new InvalidElementsStyleProviderMetaError( { context: { meta } } );\n\t\t\t}\n\n\t\t\tupdateElementStyle( {\n\t\t\t\telementId: meta.elementId,\n\t\t\t\tstyleId: args.id,\n\t\t\t\tmeta: args.meta,\n\t\t\t\tprops: args.props,\n\t\t\t} );\n\t\t},\n\t},\n\tsubscribe: ( cb ) => listenTo( styleRerenderEvents, cb ),\n\treservedLabel: LOCAL_STYLES_RESERVED_LABEL,\n} satisfies StylesProvider;\n\ntype ElementsMeta = {\n\telementId: string;\n};\n\nfunction isValidElementsMeta( meta: Record< string, unknown > ): meta is ElementsMeta {\n\treturn 'elementId' in meta && typeof meta.elementId === 'string' && !! meta.elementId;\n}\n","import { createError } from '@elementor/utils';\n\nexport const InvalidElementsStyleProviderMetaError = createError< { meta: Record< string, unknown > } >( {\n\tcode: 'invalid_elements_style_provider_meta',\n\tmessage: 'Invalid elements style provider meta.',\n} );\n","import { getWidgetsCache } from '@elementor/editor-elements';\n\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nconst ELEMENTS_BASE_STYLES_PROVIDER_KEY = 'element-base-styles';\n\nexport const elementBaseStylesProvider: StylesProvider = {\n\tkey: ELEMENTS_BASE_STYLES_PROVIDER_KEY,\n\tpriority: 10,\n\tactions: {\n\t\tget() {\n\t\t\tconst widgetsCache = getWidgetsCache();\n\n\t\t\treturn Object.values( widgetsCache ?? {} ).flatMap( ( widget ) =>\n\t\t\t\tObject.values( widget.base_styles ?? {} )\n\t\t\t);\n\t\t},\n\n\t\tgetById( id ) {\n\t\t\treturn this.get().find( ( style ) => style.id === id ) ?? null;\n\t\t},\n\t},\n\tsubscribe: () => {\n\t\treturn () => {};\n\t},\n};\n","import { elementBaseStylesProvider } from './element-base-styles-provider';\nimport { elementsStylesProvider } from './elements-styles-provider';\nimport { stylesRepository } from './styles-repository';\n\nexport function init() {\n\tstylesRepository.register( elementsStylesProvider );\n\tstylesRepository.register( elementBaseStylesProvider );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACmCA,IAAM,uBAAuB;AAEtB,IAAM,yBAAyB,MAAM;AAC3C,QAAM,YAA8B,CAAC;AAErC,QAAM,eAAe,MAAM;AAC1B,WAAO,UAAU,MAAO,CAAE,EAAE,KAAM,CAAE,GAAG,MAAS,EAAE,WAAW,EAAE,WAAW,KAAK,CAAI;AAAA,EACpF;AAEA,QAAM,WAAW,CAAE,aAA8B;AAChD,cAAU,KAAM,QAAS;AAAA,EAC1B;AAEA,QAAM,MAAM,CAAE,OAAa,CAAC,MAAO;AAClC,WAAO,aAAa,EAAE,QAAS,CAAE,aAAc,SAAS,QAAQ,IAAK,IAAK,CAAE;AAAA,EAC7E;AAEA,QAAM,YAAY,CAAE,OAAoB;AACvC,UAAM,eAAe,UAAU,IAAK,CAAE,aAAc;AACnD,aAAO,SAAS,UAAW,EAAG;AAAA,IAC/B,CAAE;AAEF,WAAO,MAAM;AACZ,mBAAa,QAAS,CAAE,gBAAiB,YAAY,CAAE;AAAA,IACxD;AAAA,EACD;AAEA,QAAM,mBAAmB,CAAE,QAAiB;AAC3C,WAAO,UAAU,KAAM,CAAE,aAAc,SAAS,QAAQ,GAAI;AAAA,EAC7D;AAEA,QAAM,eAAe,CAAE,aAAsB;AAC5C,UAAM,UAAU,IAAI;AACpB,UAAM,iBAAiB,UAAU,IAAK,CAAE,EAAE,cAAc,MAAO,aAAc,EAAE,OAAQ,OAAQ;AAE/F,QAAK,eAAe,SAAU,QAAS,GAAI;AAC1C,aAAO;AAAA,IACR;AAEA,QAAK,CAAE,SAAS,QAAS;AACxB,aAAO;AAAA,IACR;AAEA,WAAO,QAAQ,KAAM,CAAE,EAAE,MAAM,MAAO,MAAM,YAAY,MAAM,SAAS,YAAY,CAAE;AAAA,EACtF;AAEA,QAAM,eAAe,CAAE,aAAsB,qBAAqB,KAAM,QAAS;AAEjF,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;;;AC1FO,IAAM,mBAAmB,uBAAuB;;;ACFvD,mBAAsC;AAI/B,SAAS,eAAe;AAC9B,QAAM,CAAE,EAAE,QAAS,QAAI,yBAAY,CAAE,SAAU,CAAE,MAAM,KAAM;AAE7D,8BAAW,MAAM,iBAAiB,UAAW,QAAS,GAAG,CAAC,CAAE;AAE5D,SAAO,iBAAiB,aAAa;AACtC;;;ACVA,IAAAA,gBAAwB;AAQjB,SAAS,6BAA6B;AAC5C,aAAO,uBAAS,MAAM;AACrB,WAAO,iBACL,aAAa,EACb,IAA2B,CAAE,aAAc;AAC3C,UAAK,CAAE,SAAS,QAAQ,QAAS;AAChC,eAAO;AAAA,MACR;AAEA,aAAO,CAAE,UAAU,SAAS,QAAQ,MAAO;AAAA,IAC5C,CAAE,EACD,OAAQ,CAAE,SAAU,CAAC,CAAE,IAAK;AAAA,EAC/B,GAAG,CAAC,CAAE;AACP;;;ACrBA,6BAAuF;AACvF,gCAA8C;;;ACD9C,mBAA4B;AAErB,IAAM,4CAAwC,0BAAoD;AAAA,EACxG,MAAM;AAAA,EACN,SAAS;AACV,CAAE;;;ADCK,IAAM,+BAA+B;AACrC,IAAM,8BAA8B;AAEpC,IAAM,yBAAyB;AAAA,EACrC,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,IACR,KAAK,CAAE,OAAO,CAAC,MAAO;AACrB,UAAI,eAAW,oCAAY;AAE3B,UAAK,oBAAqB,IAAK,GAAI;AAClC,mBAAW,SAAS,OAAQ,CAAE,YAAa,QAAQ,OAAO,KAAK,SAAU;AAAA,MAC1E;AAEA,aAAO,SAAS,QAAS,CAAE,YAAa,OAAO,OAAQ,QAAQ,MAAM,IAAK,QAAS,KAAK,CAAC,CAAE,CAAE;AAAA,IAC9F;AAAA,IAEA,SAAS,CAAE,IAAI,OAAO,CAAC,MAAO;AAC7B,UAAK,CAAE,oBAAqB,IAAK,GAAI;AACpC,cAAM,IAAI,sCAAuC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAE;AAAA,MACxE;AAEA,YAAM,aAAS,yCAAkB,KAAK,SAAU,KAAK,CAAC;AAEtD,aAAO,OAAQ,EAAG,KAAK;AAAA,IACxB;AAAA,IAEA,aAAa,CAAE,MAAM,OAAO,CAAC,MAAO;AACnC,UAAK,CAAE,oBAAqB,IAAK,GAAI;AACpC,cAAM,IAAI,sCAAuC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAE;AAAA,MACxE;AAEA,qDAAoB;AAAA,QACnB,WAAW,KAAK;AAAA,QAChB,SAAS,KAAK;AAAA,QACd,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,MACb,CAAE;AAAA,IACH;AAAA,EACD;AAAA,EACA,WAAW,CAAE,WAAQ,0BAAAC,mBAAU,4CAAqB,EAAG;AAAA,EACvD,eAAe;AAChB;AAMA,SAAS,oBAAqB,MAAwD;AACrF,SAAO,eAAe,QAAQ,OAAO,KAAK,cAAc,YAAY,CAAC,CAAE,KAAK;AAC7E;;;AExDA,IAAAC,0BAAgC;AAIhC,IAAM,oCAAoC;AAEnC,IAAM,4BAA4C;AAAA,EACxD,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,IACR,MAAM;AACL,YAAM,mBAAe,yCAAgB;AAErC,aAAO,OAAO,OAAQ,gBAAgB,CAAC,CAAE,EAAE;AAAA,QAAS,CAAE,WACrD,OAAO,OAAQ,OAAO,eAAe,CAAC,CAAE;AAAA,MACzC;AAAA,IACD;AAAA,IAEA,QAAS,IAAK;AACb,aAAO,KAAK,IAAI,EAAE,KAAM,CAAE,UAAW,MAAM,OAAO,EAAG,KAAK;AAAA,IAC3D;AAAA,EACD;AAAA,EACA,WAAW,MAAM;AAChB,WAAO,MAAM;AAAA,IAAC;AAAA,EACf;AACD;;;ACrBO,SAAS,OAAO;AACtB,mBAAiB,SAAU,sBAAuB;AAClD,mBAAiB,SAAU,yBAA0B;AACtD;;;ARQA,KAAK;","names":["import_react","listenTo","import_editor_elements"]}
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/utils/create-styles-repository.ts
2
+ var VALID_SELECTOR_REGEX = /^[a-zA-Z0-9_-]+$/;
2
3
  var createStylesRepository = () => {
3
4
  const providers = [];
4
5
  const getProviders = () => {
@@ -7,9 +8,6 @@ var createStylesRepository = () => {
7
8
  const register = (provider) => {
8
9
  providers.push(provider);
9
10
  };
10
- const allByProvider = (meta = {}) => {
11
- return getProviders().map((provider) => [provider, provider.actions.get(meta)]);
12
- };
13
11
  const all = (meta = {}) => {
14
12
  return getProviders().flatMap((provider) => provider.actions.get(meta));
15
13
  };
@@ -24,25 +22,38 @@ var createStylesRepository = () => {
24
22
  const getProviderByKey = (key) => {
25
23
  return providers.find((provider) => provider.key === key);
26
24
  };
25
+ const isLabelExist = (newLabel) => {
26
+ const classes = all();
27
+ const reservedLabels = providers.map(({ reservedLabel }) => reservedLabel).filter(Boolean);
28
+ if (reservedLabels.includes(newLabel)) {
29
+ return true;
30
+ }
31
+ if (!classes?.length) {
32
+ return false;
33
+ }
34
+ return classes.some(({ label }) => label.toLowerCase() === newLabel.toLowerCase());
35
+ };
36
+ const isLabelValid = (newLabel) => VALID_SELECTOR_REGEX.test(newLabel);
27
37
  return {
28
38
  all,
29
- allByProvider,
30
39
  register,
31
40
  subscribe,
32
41
  getProviders,
33
- getProviderByKey
42
+ getProviderByKey,
43
+ isLabelExist,
44
+ isLabelValid
34
45
  };
35
46
  };
36
47
 
37
48
  // src/styles-repository.ts
38
49
  var stylesRepository = createStylesRepository();
39
50
 
40
- // src/hooks/use-all-styles-by-provider.ts
51
+ // src/hooks/use-providers.ts
41
52
  import { useEffect, useReducer } from "react";
42
- function useAllStylesByProvider(meta = {}) {
53
+ function useProviders() {
43
54
  const [, rerender] = useReducer((prev) => !prev, false);
44
55
  useEffect(() => stylesRepository.subscribe(rerender), []);
45
- return stylesRepository.allByProvider(meta);
56
+ return stylesRepository.getProviders();
46
57
  }
47
58
 
48
59
  // src/hooks/use-create-actions-by-provider.ts
@@ -59,39 +70,71 @@ function useCreateActionsByProvider() {
59
70
  }
60
71
 
61
72
  // src/elements-styles-provider.ts
62
- import { ELEMENT_STYLE_CHANGE_EVENT, getElements } from "@elementor/editor-elements";
63
- import { __privateListenTo as listenTo, commandEndEvent, windowEvent } from "@elementor/editor-v1-adapters";
73
+ import { getElements, getElementStyles, styleRerenderEvents, updateElementStyle } from "@elementor/editor-elements";
74
+ import { __privateListenTo as listenTo } from "@elementor/editor-v1-adapters";
75
+
76
+ // src/errors.ts
77
+ import { createError } from "@elementor/utils";
78
+ var InvalidElementsStyleProviderMetaError = createError({
79
+ code: "invalid_elements_style_provider_meta",
80
+ message: "Invalid elements style provider meta."
81
+ });
82
+
83
+ // src/elements-styles-provider.ts
64
84
  var ELEMENTS_STYLES_PROVIDER_KEY = "elements";
85
+ var LOCAL_STYLES_RESERVED_LABEL = "local";
65
86
  var elementsStylesProvider = {
66
87
  key: ELEMENTS_STYLES_PROVIDER_KEY,
67
88
  priority: 50,
68
89
  actions: {
69
90
  get: (meta = {}) => {
70
91
  let elements = getElements();
71
- if ("elementId" in meta && meta.elementId) {
92
+ if (isValidElementsMeta(meta)) {
72
93
  elements = elements.filter((element) => element.id === meta.elementId);
73
94
  }
74
95
  return elements.flatMap((element) => Object.values(element.model.get("styles") ?? {}));
96
+ },
97
+ getById: (id, meta = {}) => {
98
+ if (!isValidElementsMeta(meta)) {
99
+ throw new InvalidElementsStyleProviderMetaError({ context: { meta } });
100
+ }
101
+ const styles = getElementStyles(meta.elementId) ?? {};
102
+ return styles[id] ?? null;
103
+ },
104
+ updateProps: (args, meta = {}) => {
105
+ if (!isValidElementsMeta(meta)) {
106
+ throw new InvalidElementsStyleProviderMetaError({ context: { meta } });
107
+ }
108
+ updateElementStyle({
109
+ elementId: meta.elementId,
110
+ styleId: args.id,
111
+ meta: args.meta,
112
+ props: args.props
113
+ });
75
114
  }
76
115
  },
77
- subscribe: (cb) => {
78
- return listenTo(
79
- [commandEndEvent("editor/documents/attach-preview"), windowEvent(ELEMENT_STYLE_CHANGE_EVENT)],
80
- cb
81
- );
82
- }
116
+ subscribe: (cb) => listenTo(styleRerenderEvents, cb),
117
+ reservedLabel: LOCAL_STYLES_RESERVED_LABEL
83
118
  };
119
+ function isValidElementsMeta(meta) {
120
+ return "elementId" in meta && typeof meta.elementId === "string" && !!meta.elementId;
121
+ }
84
122
 
85
123
  // src/element-base-styles-provider.ts
86
124
  import { getWidgetsCache } from "@elementor/editor-elements";
87
125
  var ELEMENTS_BASE_STYLES_PROVIDER_KEY = "element-base-styles";
88
126
  var elementBaseStylesProvider = {
89
127
  key: ELEMENTS_BASE_STYLES_PROVIDER_KEY,
90
- priority: 60,
128
+ priority: 10,
91
129
  actions: {
92
- get: () => {
130
+ get() {
93
131
  const widgetsCache = getWidgetsCache();
94
- return Object.values(widgetsCache ?? {}).flatMap((widget) => widget.base_styles ?? []);
132
+ return Object.values(widgetsCache ?? {}).flatMap(
133
+ (widget) => Object.values(widget.base_styles ?? {})
134
+ );
135
+ },
136
+ getById(id) {
137
+ return this.get().find((style) => style.id === id) ?? null;
95
138
  }
96
139
  },
97
140
  subscribe: () => {
@@ -110,8 +153,9 @@ function init() {
110
153
  init();
111
154
  export {
112
155
  ELEMENTS_STYLES_PROVIDER_KEY,
156
+ LOCAL_STYLES_RESERVED_LABEL,
113
157
  stylesRepository,
114
- useAllStylesByProvider,
115
- useCreateActionsByProvider
158
+ useCreateActionsByProvider,
159
+ useProviders
116
160
  };
117
161
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/create-styles-repository.ts","../src/styles-repository.ts","../src/hooks/use-all-styles-by-provider.ts","../src/hooks/use-create-actions-by-provider.ts","../src/elements-styles-provider.ts","../src/element-base-styles-provider.ts","../src/init.ts","../src/index.ts"],"sourcesContent":["import { type StyleDefinition } from '@elementor/editor-styles';\n\nexport type MakeOptional< T, K extends keyof T > = Omit< T, K > & Partial< T >;\n\nexport type GetActionPayload = Record< string, unknown >;\nexport type CreateActionPayload = MakeOptional< StyleDefinition, 'id' | 'type' | 'variants' >;\nexport type UpdateActionPayload = MakeOptional< StyleDefinition, 'label' | 'variants' | 'type' >;\n\nexport type StylesProvider = {\n\tkey: string;\n\tpriority: number;\n\tactions: {\n\t\tget: ( meta?: GetActionPayload ) => StyleDefinition[];\n\t\tcreate?: ( data: CreateActionPayload ) => Promise< StyleDefinition >;\n\t\tupdate?: ( data: UpdateActionPayload ) => Promise< StyleDefinition >;\n\t};\n\tsubscribe: ( callback: () => void ) => () => void;\n\tlabels?: {\n\t\tsingular: string;\n\t\tplural: string;\n\t};\n};\n\nexport const createStylesRepository = () => {\n\tconst providers: StylesProvider[] = [];\n\n\tconst getProviders = () => {\n\t\treturn providers.slice( 0 ).sort( ( a, b ) => ( a.priority > b.priority ? -1 : 1 ) );\n\t};\n\n\tconst register = ( provider: StylesProvider ) => {\n\t\tproviders.push( provider );\n\t};\n\n\tconst allByProvider = ( meta: GetActionPayload = {} ) => {\n\t\treturn getProviders().map( ( provider ) => [ provider, provider.actions.get( meta ) ] as const );\n\t};\n\n\tconst all = ( meta: GetActionPayload = {} ) => {\n\t\treturn getProviders().flatMap( ( provider ) => provider.actions.get( meta ) );\n\t};\n\n\tconst subscribe = ( cb: () => void ) => {\n\t\tconst unsubscribes = providers.map( ( provider ) => {\n\t\t\treturn provider.subscribe( cb );\n\t\t} );\n\n\t\treturn () => {\n\t\t\tunsubscribes.forEach( ( unsubscribe ) => unsubscribe() );\n\t\t};\n\t};\n\n\tconst getProviderByKey = ( key: string ) => {\n\t\treturn providers.find( ( provider ) => provider.key === key );\n\t};\n\n\treturn {\n\t\tall,\n\t\tallByProvider,\n\t\tregister,\n\t\tsubscribe,\n\t\tgetProviders,\n\t\tgetProviderByKey,\n\t};\n};\n","import { createStylesRepository } from './utils/create-styles-repository';\n\nexport const stylesRepository = createStylesRepository();\n","import { useEffect, useReducer } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\nimport { type GetActionPayload } from '../utils/create-styles-repository';\n\nexport function useAllStylesByProvider( meta: GetActionPayload = {} ) {\n\tconst [ , rerender ] = useReducer( ( prev ) => ! prev, false );\n\n\tuseEffect( () => stylesRepository.subscribe( rerender ), [] );\n\n\treturn stylesRepository.allByProvider( meta );\n}\n","import { useMemo } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\nimport { type StylesProvider } from '../utils/create-styles-repository';\n\ntype CreateAction = Required< StylesProvider[ 'actions' ] >[ 'create' ];\ntype CreateTuple = [ StylesProvider, CreateAction ];\n\nexport function useCreateActionsByProvider() {\n\treturn useMemo( () => {\n\t\treturn stylesRepository\n\t\t\t.getProviders()\n\t\t\t.map< CreateTuple | null >( ( provider ) => {\n\t\t\t\tif ( ! provider.actions.create ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn [ provider, provider.actions.create ];\n\t\t\t} )\n\t\t\t.filter( ( item ) => !! item );\n\t}, [] );\n}\n","import { ELEMENT_STYLE_CHANGE_EVENT, getElements } from '@elementor/editor-elements';\nimport { __privateListenTo as listenTo, commandEndEvent, windowEvent } from '@elementor/editor-v1-adapters';\n\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nexport const ELEMENTS_STYLES_PROVIDER_KEY = 'elements';\n\nexport const elementsStylesProvider: StylesProvider = {\n\tkey: ELEMENTS_STYLES_PROVIDER_KEY,\n\tpriority: 50,\n\tactions: {\n\t\tget: ( meta = {} ) => {\n\t\t\tlet elements = getElements();\n\n\t\t\tif ( 'elementId' in meta && meta.elementId ) {\n\t\t\t\telements = elements.filter( ( element ) => element.id === meta.elementId );\n\t\t\t}\n\n\t\t\treturn elements.flatMap( ( element ) => Object.values( element.model.get( 'styles' ) ?? {} ) );\n\t\t},\n\t},\n\tsubscribe: ( cb ) => {\n\t\treturn listenTo(\n\t\t\t[ commandEndEvent( 'editor/documents/attach-preview' ), windowEvent( ELEMENT_STYLE_CHANGE_EVENT ) ],\n\t\t\tcb\n\t\t);\n\t},\n};\n","import { getWidgetsCache } from '@elementor/editor-elements';\n\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nconst ELEMENTS_BASE_STYLES_PROVIDER_KEY = 'element-base-styles';\n\nexport const elementBaseStylesProvider: StylesProvider = {\n\tkey: ELEMENTS_BASE_STYLES_PROVIDER_KEY,\n\tpriority: 60,\n\tactions: {\n\t\tget: () => {\n\t\t\tconst widgetsCache = getWidgetsCache();\n\n\t\t\treturn Object.values( widgetsCache ?? {} ).flatMap( ( widget ) => widget.base_styles ?? [] );\n\t\t},\n\t},\n\tsubscribe: () => {\n\t\treturn () => {};\n\t},\n};\n","import { elementBaseStylesProvider } from './element-base-styles-provider';\nimport { elementsStylesProvider } from './elements-styles-provider';\nimport { stylesRepository } from './styles-repository';\n\nexport function init() {\n\tstylesRepository.register( elementsStylesProvider );\n\tstylesRepository.register( elementBaseStylesProvider );\n}\n","export {\n\ttype StylesProvider,\n\ttype CreateActionPayload,\n\ttype GetActionPayload,\n\ttype UpdateActionPayload,\n} from './utils/create-styles-repository';\n\nexport { stylesRepository } from './styles-repository';\nexport { useAllStylesByProvider } from './hooks/use-all-styles-by-provider';\nexport { useCreateActionsByProvider } from './hooks/use-create-actions-by-provider';\n\nexport { ELEMENTS_STYLES_PROVIDER_KEY } from './elements-styles-provider';\n\nimport { init } from './init';\n\ninit();\n"],"mappings":";AAuBO,IAAM,yBAAyB,MAAM;AAC3C,QAAM,YAA8B,CAAC;AAErC,QAAM,eAAe,MAAM;AAC1B,WAAO,UAAU,MAAO,CAAE,EAAE,KAAM,CAAE,GAAG,MAAS,EAAE,WAAW,EAAE,WAAW,KAAK,CAAI;AAAA,EACpF;AAEA,QAAM,WAAW,CAAE,aAA8B;AAChD,cAAU,KAAM,QAAS;AAAA,EAC1B;AAEA,QAAM,gBAAgB,CAAE,OAAyB,CAAC,MAAO;AACxD,WAAO,aAAa,EAAE,IAAK,CAAE,aAAc,CAAE,UAAU,SAAS,QAAQ,IAAK,IAAK,CAAE,CAAW;AAAA,EAChG;AAEA,QAAM,MAAM,CAAE,OAAyB,CAAC,MAAO;AAC9C,WAAO,aAAa,EAAE,QAAS,CAAE,aAAc,SAAS,QAAQ,IAAK,IAAK,CAAE;AAAA,EAC7E;AAEA,QAAM,YAAY,CAAE,OAAoB;AACvC,UAAM,eAAe,UAAU,IAAK,CAAE,aAAc;AACnD,aAAO,SAAS,UAAW,EAAG;AAAA,IAC/B,CAAE;AAEF,WAAO,MAAM;AACZ,mBAAa,QAAS,CAAE,gBAAiB,YAAY,CAAE;AAAA,IACxD;AAAA,EACD;AAEA,QAAM,mBAAmB,CAAE,QAAiB;AAC3C,WAAO,UAAU,KAAM,CAAE,aAAc,SAAS,QAAQ,GAAI;AAAA,EAC7D;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;;;AC9DO,IAAM,mBAAmB,uBAAuB;;;ACFvD,SAAS,WAAW,kBAAkB;AAK/B,SAAS,uBAAwB,OAAyB,CAAC,GAAI;AACrE,QAAM,CAAE,EAAE,QAAS,IAAI,WAAY,CAAE,SAAU,CAAE,MAAM,KAAM;AAE7D,YAAW,MAAM,iBAAiB,UAAW,QAAS,GAAG,CAAC,CAAE;AAE5D,SAAO,iBAAiB,cAAe,IAAK;AAC7C;;;ACXA,SAAS,eAAe;AAQjB,SAAS,6BAA6B;AAC5C,SAAO,QAAS,MAAM;AACrB,WAAO,iBACL,aAAa,EACb,IAA2B,CAAE,aAAc;AAC3C,UAAK,CAAE,SAAS,QAAQ,QAAS;AAChC,eAAO;AAAA,MACR;AAEA,aAAO,CAAE,UAAU,SAAS,QAAQ,MAAO;AAAA,IAC5C,CAAE,EACD,OAAQ,CAAE,SAAU,CAAC,CAAE,IAAK;AAAA,EAC/B,GAAG,CAAC,CAAE;AACP;;;ACrBA,SAAS,4BAA4B,mBAAmB;AACxD,SAAS,qBAAqB,UAAU,iBAAiB,mBAAmB;AAIrE,IAAM,+BAA+B;AAErC,IAAM,yBAAyC;AAAA,EACrD,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,IACR,KAAK,CAAE,OAAO,CAAC,MAAO;AACrB,UAAI,WAAW,YAAY;AAE3B,UAAK,eAAe,QAAQ,KAAK,WAAY;AAC5C,mBAAW,SAAS,OAAQ,CAAE,YAAa,QAAQ,OAAO,KAAK,SAAU;AAAA,MAC1E;AAEA,aAAO,SAAS,QAAS,CAAE,YAAa,OAAO,OAAQ,QAAQ,MAAM,IAAK,QAAS,KAAK,CAAC,CAAE,CAAE;AAAA,IAC9F;AAAA,EACD;AAAA,EACA,WAAW,CAAE,OAAQ;AACpB,WAAO;AAAA,MACN,CAAE,gBAAiB,iCAAkC,GAAG,YAAa,0BAA2B,CAAE;AAAA,MAClG;AAAA,IACD;AAAA,EACD;AACD;;;AC3BA,SAAS,uBAAuB;AAIhC,IAAM,oCAAoC;AAEnC,IAAM,4BAA4C;AAAA,EACxD,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,IACR,KAAK,MAAM;AACV,YAAM,eAAe,gBAAgB;AAErC,aAAO,OAAO,OAAQ,gBAAgB,CAAC,CAAE,EAAE,QAAS,CAAE,WAAY,OAAO,eAAe,CAAC,CAAE;AAAA,IAC5F;AAAA,EACD;AAAA,EACA,WAAW,MAAM;AAChB,WAAO,MAAM;AAAA,IAAC;AAAA,EACf;AACD;;;ACfO,SAAS,OAAO;AACtB,mBAAiB,SAAU,sBAAuB;AAClD,mBAAiB,SAAU,yBAA0B;AACtD;;;ACQA,KAAK;","names":[]}
1
+ {"version":3,"sources":["../src/utils/create-styles-repository.ts","../src/styles-repository.ts","../src/hooks/use-providers.ts","../src/hooks/use-create-actions-by-provider.ts","../src/elements-styles-provider.ts","../src/errors.ts","../src/element-base-styles-provider.ts","../src/init.ts","../src/index.ts"],"sourcesContent":["import { type Props } from '@elementor/editor-props';\nimport { type StyleDefinition, type StyleDefinitionID, type StyleDefinitionVariant } from '@elementor/editor-styles';\n\ntype MakeOptional< T, K extends keyof T > = Omit< T, K > & Partial< T >;\n\nexport type UpdateActionPayload = MakeOptional< StyleDefinition, 'label' | 'variants' | 'type' >;\n\nexport type UpdatePropsActionPayload = {\n\tid: StyleDefinitionID;\n\tmeta: StyleDefinitionVariant[ 'meta' ];\n\tprops: Props;\n};\n\nexport type Meta = Record< string, unknown >;\n\nexport type StylesProvider = {\n\tkey: string;\n\tpriority: number;\n\tactions: {\n\t\tget: ( meta?: Meta ) => StyleDefinition[];\n\t\tgetById: ( id: StyleDefinitionID, meta?: Meta ) => StyleDefinition | null;\n\t\tcreate?: ( label: StyleDefinition[ 'label' ] ) => StyleDefinitionID;\n\t\tdelete?: ( id: StyleDefinitionID ) => void;\n\t\tsetOrder?: ( order: StyleDefinitionID[] ) => void;\n\t\tupdate?: ( data: UpdateActionPayload ) => void;\n\t\tupdateProps?: ( args: UpdatePropsActionPayload, meta?: Meta ) => void;\n\t};\n\tsubscribe: ( callback: () => void ) => () => void;\n\tlabels?: {\n\t\tsingular: string;\n\t\tplural: string;\n\t};\n\treservedLabel?: string;\n};\n\nconst VALID_SELECTOR_REGEX = /^[a-zA-Z0-9_-]+$/;\n\nexport const createStylesRepository = () => {\n\tconst providers: StylesProvider[] = [];\n\n\tconst getProviders = () => {\n\t\treturn providers.slice( 0 ).sort( ( a, b ) => ( a.priority > b.priority ? -1 : 1 ) );\n\t};\n\n\tconst register = ( provider: StylesProvider ) => {\n\t\tproviders.push( provider );\n\t};\n\n\tconst all = ( meta: Meta = {} ) => {\n\t\treturn getProviders().flatMap( ( provider ) => provider.actions.get( meta ) );\n\t};\n\n\tconst subscribe = ( cb: () => void ) => {\n\t\tconst unsubscribes = providers.map( ( provider ) => {\n\t\t\treturn provider.subscribe( cb );\n\t\t} );\n\n\t\treturn () => {\n\t\t\tunsubscribes.forEach( ( unsubscribe ) => unsubscribe() );\n\t\t};\n\t};\n\n\tconst getProviderByKey = ( key: string ) => {\n\t\treturn providers.find( ( provider ) => provider.key === key );\n\t};\n\n\tconst isLabelExist = ( newLabel: string ) => {\n\t\tconst classes = all();\n\t\tconst reservedLabels = providers.map( ( { reservedLabel } ) => reservedLabel ).filter( Boolean );\n\n\t\tif ( reservedLabels.includes( newLabel ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( ! classes?.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn classes.some( ( { label } ) => label.toLowerCase() === newLabel.toLowerCase() );\n\t};\n\n\tconst isLabelValid = ( newLabel: string ) => VALID_SELECTOR_REGEX.test( newLabel );\n\n\treturn {\n\t\tall,\n\t\tregister,\n\t\tsubscribe,\n\t\tgetProviders,\n\t\tgetProviderByKey,\n\t\tisLabelExist,\n\t\tisLabelValid,\n\t};\n};\n","import { createStylesRepository } from './utils/create-styles-repository';\n\nexport const stylesRepository = createStylesRepository();\n","import { useEffect, useReducer } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\n\nexport function useProviders() {\n\tconst [ , rerender ] = useReducer( ( prev ) => ! prev, false );\n\n\tuseEffect( () => stylesRepository.subscribe( rerender ), [] );\n\n\treturn stylesRepository.getProviders();\n}\n","import { useMemo } from 'react';\n\nimport { stylesRepository } from '../styles-repository';\nimport { type StylesProvider } from '../utils/create-styles-repository';\n\ntype CreateAction = Required< StylesProvider[ 'actions' ] >[ 'create' ];\ntype CreateTuple = [ StylesProvider, CreateAction ];\n\nexport function useCreateActionsByProvider() {\n\treturn useMemo( () => {\n\t\treturn stylesRepository\n\t\t\t.getProviders()\n\t\t\t.map< CreateTuple | null >( ( provider ) => {\n\t\t\t\tif ( ! provider.actions.create ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn [ provider, provider.actions.create ];\n\t\t\t} )\n\t\t\t.filter( ( item ) => !! item );\n\t}, [] );\n}\n","import { getElements, getElementStyles, styleRerenderEvents, updateElementStyle } from '@elementor/editor-elements';\nimport { __privateListenTo as listenTo } from '@elementor/editor-v1-adapters';\n\nimport { InvalidElementsStyleProviderMetaError } from './errors';\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nexport const ELEMENTS_STYLES_PROVIDER_KEY = 'elements';\nexport const LOCAL_STYLES_RESERVED_LABEL = 'local';\n\nexport const elementsStylesProvider = {\n\tkey: ELEMENTS_STYLES_PROVIDER_KEY,\n\tpriority: 50,\n\tactions: {\n\t\tget: ( meta = {} ) => {\n\t\t\tlet elements = getElements();\n\n\t\t\tif ( isValidElementsMeta( meta ) ) {\n\t\t\t\telements = elements.filter( ( element ) => element.id === meta.elementId );\n\t\t\t}\n\n\t\t\treturn elements.flatMap( ( element ) => Object.values( element.model.get( 'styles' ) ?? {} ) );\n\t\t},\n\n\t\tgetById: ( id, meta = {} ) => {\n\t\t\tif ( ! isValidElementsMeta( meta ) ) {\n\t\t\t\tthrow new InvalidElementsStyleProviderMetaError( { context: { meta } } );\n\t\t\t}\n\n\t\t\tconst styles = getElementStyles( meta.elementId ) ?? {};\n\n\t\t\treturn styles[ id ] ?? null;\n\t\t},\n\n\t\tupdateProps: ( args, meta = {} ) => {\n\t\t\tif ( ! isValidElementsMeta( meta ) ) {\n\t\t\t\tthrow new InvalidElementsStyleProviderMetaError( { context: { meta } } );\n\t\t\t}\n\n\t\t\tupdateElementStyle( {\n\t\t\t\telementId: meta.elementId,\n\t\t\t\tstyleId: args.id,\n\t\t\t\tmeta: args.meta,\n\t\t\t\tprops: args.props,\n\t\t\t} );\n\t\t},\n\t},\n\tsubscribe: ( cb ) => listenTo( styleRerenderEvents, cb ),\n\treservedLabel: LOCAL_STYLES_RESERVED_LABEL,\n} satisfies StylesProvider;\n\ntype ElementsMeta = {\n\telementId: string;\n};\n\nfunction isValidElementsMeta( meta: Record< string, unknown > ): meta is ElementsMeta {\n\treturn 'elementId' in meta && typeof meta.elementId === 'string' && !! meta.elementId;\n}\n","import { createError } from '@elementor/utils';\n\nexport const InvalidElementsStyleProviderMetaError = createError< { meta: Record< string, unknown > } >( {\n\tcode: 'invalid_elements_style_provider_meta',\n\tmessage: 'Invalid elements style provider meta.',\n} );\n","import { getWidgetsCache } from '@elementor/editor-elements';\n\nimport { type StylesProvider } from './utils/create-styles-repository';\n\nconst ELEMENTS_BASE_STYLES_PROVIDER_KEY = 'element-base-styles';\n\nexport const elementBaseStylesProvider: StylesProvider = {\n\tkey: ELEMENTS_BASE_STYLES_PROVIDER_KEY,\n\tpriority: 10,\n\tactions: {\n\t\tget() {\n\t\t\tconst widgetsCache = getWidgetsCache();\n\n\t\t\treturn Object.values( widgetsCache ?? {} ).flatMap( ( widget ) =>\n\t\t\t\tObject.values( widget.base_styles ?? {} )\n\t\t\t);\n\t\t},\n\n\t\tgetById( id ) {\n\t\t\treturn this.get().find( ( style ) => style.id === id ) ?? null;\n\t\t},\n\t},\n\tsubscribe: () => {\n\t\treturn () => {};\n\t},\n};\n","import { elementBaseStylesProvider } from './element-base-styles-provider';\nimport { elementsStylesProvider } from './elements-styles-provider';\nimport { stylesRepository } from './styles-repository';\n\nexport function init() {\n\tstylesRepository.register( elementsStylesProvider );\n\tstylesRepository.register( elementBaseStylesProvider );\n}\n","export {\n\ttype StylesProvider,\n\ttype UpdateActionPayload,\n\ttype Meta,\n\ttype UpdatePropsActionPayload,\n} from './utils/create-styles-repository';\n\nexport { stylesRepository } from './styles-repository';\nexport { useProviders } from './hooks/use-providers';\nexport { useCreateActionsByProvider } from './hooks/use-create-actions-by-provider';\n\nexport { ELEMENTS_STYLES_PROVIDER_KEY, LOCAL_STYLES_RESERVED_LABEL } from './elements-styles-provider';\n\nimport { init } from './init';\n\ninit();\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-styles-repository",
3
3
  "description": "Elementor Editor Styles Repository",
4
- "version": "0.5.0",
4
+ "version": "0.7.0",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -33,11 +33,16 @@
33
33
  "dev": "tsup --config=../../tsup.dev.ts"
34
34
  },
35
35
  "dependencies": {
36
- "@elementor/editor-elements": "0.5.0",
37
- "@elementor/editor-styles": "0.5.3",
38
- "@elementor/editor-v1-adapters": "0.9.0"
36
+ "@elementor/editor-elements": "0.5.2",
37
+ "@elementor/editor-props": "0.9.0",
38
+ "@elementor/editor-styles": "0.5.5",
39
+ "@elementor/editor-v1-adapters": "0.10.0",
40
+ "@elementor/utils": "0.3.1"
39
41
  },
40
42
  "peerDependencies": {
41
43
  "react": "^18.3.1"
44
+ },
45
+ "devDependencies": {
46
+ "tsup": "^8.3.5"
42
47
  }
43
48
  }
@@ -9,10 +9,15 @@ describe( 'elementBaseStylesProvider', () => {
9
9
  beforeEach( () => {
10
10
  jest.mocked( getWidgetsCache ).mockReturnValue( {
11
11
  'widget-1': {
12
- base_styles: [ createMockStyleDefinition( { id: 's-1' } ), createMockStyleDefinition( { id: 's-2' } ) ],
12
+ base_styles: {
13
+ 's-1': createMockStyleDefinition( { id: 's-1' } ),
14
+ 's-2': createMockStyleDefinition( { id: 's-2' } ),
15
+ },
13
16
  },
14
17
  'widget-2': {
15
- base_styles: [ createMockStyleDefinition( { id: 's-3' } ) ],
18
+ base_styles: {
19
+ 's-3': createMockStyleDefinition( { id: 's-3' } ),
20
+ },
16
21
  },
17
22
  'widget-3': {},
18
23
  } as unknown as ReturnType< typeof getWidgetsCache > );
@@ -29,4 +34,12 @@ describe( 'elementBaseStylesProvider', () => {
29
34
  expect.objectContaining( { id: 's-3' } ),
30
35
  ] );
31
36
  } );
37
+
38
+ it( 'should return base style by id', () => {
39
+ // Act.
40
+ const style = elementBaseStylesProvider.actions.getById( 's-1' );
41
+
42
+ // Assert.
43
+ expect( style ).toEqual( expect.objectContaining( { id: 's-1' } ) );
44
+ } );
32
45
  } );
@@ -1,7 +1,9 @@
1
1
  import { createMockElement, createMockStyleDefinition } from 'test-utils';
2
- import { getElements } from '@elementor/editor-elements';
2
+ import { getElements, getElementStyles, updateElementStyle } from '@elementor/editor-elements';
3
+ import type { StyleDefinition } from '@elementor/editor-styles';
3
4
 
4
5
  import { elementsStylesProvider } from '../elements-styles-provider';
6
+ import { InvalidElementsStyleProviderMetaError } from '../errors';
5
7
 
6
8
  jest.mock( '@elementor/editor-elements' );
7
9
 
@@ -50,4 +52,95 @@ describe( 'elementsStylesProvider', () => {
50
52
  expect.objectContaining( { id: 's-2' } ),
51
53
  ] );
52
54
  } );
55
+
56
+ it( 'should retrieve an element style by id', () => {
57
+ const styles: Record< string, StyleDefinition > = {
58
+ 'style-1': {
59
+ id: 'style-1',
60
+ label: 'Style 1',
61
+ variants: [],
62
+ type: 'class',
63
+ },
64
+ 'style-2': {
65
+ id: 'style-2',
66
+ label: 'Style 2',
67
+ variants: [],
68
+ type: 'class',
69
+ },
70
+ };
71
+
72
+ jest.mocked( getElementStyles ).mockImplementation( ( elementId ) => {
73
+ return elementId === 'test-element-id' ? styles : null;
74
+ } );
75
+
76
+ // Act.
77
+ const elementStyle = elementsStylesProvider.actions.getById( 'style-2', { elementId: 'test-element-id' } );
78
+
79
+ // Assert.
80
+ expect( elementStyle ).toStrictEqual( styles[ 'style-2' ] );
81
+ } );
82
+
83
+ it( 'should throw when trying to get a style by id without passing an element id', () => {
84
+ // Act & Assert.
85
+ expect( () => elementsStylesProvider.actions.getById( 'style', { notElementId: 'test-value' } ) ).toThrow(
86
+ new InvalidElementsStyleProviderMetaError()
87
+ );
88
+ } );
89
+
90
+ it( 'should update style props', () => {
91
+ // Act.
92
+ elementsStylesProvider.actions.updateProps(
93
+ {
94
+ id: 'test-style',
95
+ meta: {
96
+ breakpoint: null,
97
+ state: null,
98
+ },
99
+ props: {
100
+ prop: 'value',
101
+ },
102
+ },
103
+ { elementId: 'test-element' }
104
+ );
105
+
106
+ // Assert.
107
+ expect( updateElementStyle ).toHaveBeenCalledTimes( 1 );
108
+
109
+ expect( updateElementStyle ).toHaveBeenCalledWith( {
110
+ elementId: 'test-element',
111
+ styleId: 'test-style',
112
+ meta: {
113
+ breakpoint: null,
114
+ state: null,
115
+ },
116
+ props: {
117
+ prop: 'value',
118
+ },
119
+ } );
120
+ } );
121
+
122
+ it.each( [
123
+ { elementsMeta: { notElementId: 'test-value' } },
124
+ { elementsMeta: { elementId: 123 } },
125
+ { elementsMeta: { elementId: null } },
126
+ { elementsMeta: { elementId: '' } },
127
+ { elementsMeta: { elementId: {} } },
128
+ ] )( 'should throw when updating props with invalid elements meta', ( { elementsMeta } ) => {
129
+ // Act & Assert.
130
+ expect( () =>
131
+ elementsStylesProvider.actions.updateProps(
132
+ {
133
+ id: 'test-id',
134
+ meta: {
135
+ breakpoint: null,
136
+ state: null,
137
+ },
138
+ props: {
139
+ prop: 'value',
140
+ },
141
+ },
142
+ elementsMeta
143
+ )
144
+ ).toThrow( new InvalidElementsStyleProviderMetaError() );
145
+ } );
53
146
  } );
@@ -6,12 +6,18 @@ const ELEMENTS_BASE_STYLES_PROVIDER_KEY = 'element-base-styles';
6
6
 
7
7
  export const elementBaseStylesProvider: StylesProvider = {
8
8
  key: ELEMENTS_BASE_STYLES_PROVIDER_KEY,
9
- priority: 60,
9
+ priority: 10,
10
10
  actions: {
11
- get: () => {
11
+ get() {
12
12
  const widgetsCache = getWidgetsCache();
13
13
 
14
- return Object.values( widgetsCache ?? {} ).flatMap( ( widget ) => widget.base_styles ?? [] );
14
+ return Object.values( widgetsCache ?? {} ).flatMap( ( widget ) =>
15
+ Object.values( widget.base_styles ?? {} )
16
+ );
17
+ },
18
+
19
+ getById( id ) {
20
+ return this.get().find( ( style ) => style.id === id ) ?? null;
15
21
  },
16
22
  },
17
23
  subscribe: () => {
@@ -1,28 +1,57 @@
1
- import { ELEMENT_STYLE_CHANGE_EVENT, getElements } from '@elementor/editor-elements';
2
- import { __privateListenTo as listenTo, commandEndEvent, windowEvent } from '@elementor/editor-v1-adapters';
1
+ import { getElements, getElementStyles, styleRerenderEvents, updateElementStyle } from '@elementor/editor-elements';
2
+ import { __privateListenTo as listenTo } from '@elementor/editor-v1-adapters';
3
3
 
4
+ import { InvalidElementsStyleProviderMetaError } from './errors';
4
5
  import { type StylesProvider } from './utils/create-styles-repository';
5
6
 
6
7
  export const ELEMENTS_STYLES_PROVIDER_KEY = 'elements';
8
+ export const LOCAL_STYLES_RESERVED_LABEL = 'local';
7
9
 
8
- export const elementsStylesProvider: StylesProvider = {
10
+ export const elementsStylesProvider = {
9
11
  key: ELEMENTS_STYLES_PROVIDER_KEY,
10
12
  priority: 50,
11
13
  actions: {
12
14
  get: ( meta = {} ) => {
13
15
  let elements = getElements();
14
16
 
15
- if ( 'elementId' in meta && meta.elementId ) {
17
+ if ( isValidElementsMeta( meta ) ) {
16
18
  elements = elements.filter( ( element ) => element.id === meta.elementId );
17
19
  }
18
20
 
19
21
  return elements.flatMap( ( element ) => Object.values( element.model.get( 'styles' ) ?? {} ) );
20
22
  },
23
+
24
+ getById: ( id, meta = {} ) => {
25
+ if ( ! isValidElementsMeta( meta ) ) {
26
+ throw new InvalidElementsStyleProviderMetaError( { context: { meta } } );
27
+ }
28
+
29
+ const styles = getElementStyles( meta.elementId ) ?? {};
30
+
31
+ return styles[ id ] ?? null;
32
+ },
33
+
34
+ updateProps: ( args, meta = {} ) => {
35
+ if ( ! isValidElementsMeta( meta ) ) {
36
+ throw new InvalidElementsStyleProviderMetaError( { context: { meta } } );
37
+ }
38
+
39
+ updateElementStyle( {
40
+ elementId: meta.elementId,
41
+ styleId: args.id,
42
+ meta: args.meta,
43
+ props: args.props,
44
+ } );
45
+ },
21
46
  },
22
- subscribe: ( cb ) => {
23
- return listenTo(
24
- [ commandEndEvent( 'editor/documents/attach-preview' ), windowEvent( ELEMENT_STYLE_CHANGE_EVENT ) ],
25
- cb
26
- );
27
- },
47
+ subscribe: ( cb ) => listenTo( styleRerenderEvents, cb ),
48
+ reservedLabel: LOCAL_STYLES_RESERVED_LABEL,
49
+ } satisfies StylesProvider;
50
+
51
+ type ElementsMeta = {
52
+ elementId: string;
28
53
  };
54
+
55
+ function isValidElementsMeta( meta: Record< string, unknown > ): meta is ElementsMeta {
56
+ return 'elementId' in meta && typeof meta.elementId === 'string' && !! meta.elementId;
57
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { createError } from '@elementor/utils';
2
+
3
+ export const InvalidElementsStyleProviderMetaError = createError< { meta: Record< string, unknown > } >( {
4
+ code: 'invalid_elements_style_provider_meta',
5
+ message: 'Invalid elements style provider meta.',
6
+ } );
@@ -1,12 +1,11 @@
1
1
  import { useEffect, useReducer } from 'react';
2
2
 
3
3
  import { stylesRepository } from '../styles-repository';
4
- import { type GetActionPayload } from '../utils/create-styles-repository';
5
4
 
6
- export function useAllStylesByProvider( meta: GetActionPayload = {} ) {
5
+ export function useProviders() {
7
6
  const [ , rerender ] = useReducer( ( prev ) => ! prev, false );
8
7
 
9
8
  useEffect( () => stylesRepository.subscribe( rerender ), [] );
10
9
 
11
- return stylesRepository.allByProvider( meta );
10
+ return stylesRepository.getProviders();
12
11
  }
package/src/index.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  export {
2
2
  type StylesProvider,
3
- type CreateActionPayload,
4
- type GetActionPayload,
5
3
  type UpdateActionPayload,
4
+ type Meta,
5
+ type UpdatePropsActionPayload,
6
6
  } from './utils/create-styles-repository';
7
7
 
8
8
  export { stylesRepository } from './styles-repository';
9
- export { useAllStylesByProvider } from './hooks/use-all-styles-by-provider';
9
+ export { useProviders } from './hooks/use-providers';
10
10
  export { useCreateActionsByProvider } from './hooks/use-create-actions-by-provider';
11
11
 
12
- export { ELEMENTS_STYLES_PROVIDER_KEY } from './elements-styles-provider';
12
+ export { ELEMENTS_STYLES_PROVIDER_KEY, LOCAL_STYLES_RESERVED_LABEL } from './elements-styles-provider';
13
13
 
14
14
  import { init } from './init';
15
15
 
@@ -1,45 +1,37 @@
1
- import { createMockStyleDefinition } from 'test-utils';
2
- import { type StyleDefinition } from '@elementor/editor-styles';
1
+ import { createMockStyleDefinition, createMockStylesProvider } from 'test-utils';
3
2
 
4
- import { createStylesRepository, type StylesProvider } from '../create-styles-repository';
3
+ import { createStylesRepository } from '../create-styles-repository';
5
4
 
6
5
  const styleDef1 = createMockStyleDefinition( { props: { color: { $$type: 'color', value: '#dddddd' } } } );
7
6
  const styleDef2 = createMockStyleDefinition( { props: { color: { $$type: 'color', value: '#eeeeee' } } } );
8
- const styleDef3 = createMockStyleDefinition( { props: { color: { $$type: 'color', value: '#111111' } } } );
9
7
 
10
8
  describe( 'createStylesRepository', () => {
11
9
  it( 'should get all the style defs from all providers ordered by priority', () => {
12
10
  // Arrange
13
11
  const repo = createStylesRepository();
14
12
 
15
- repo.register( createMockProvider( 'mock1', 10, [ styleDef1 ] ).provider );
16
- repo.register( createMockProvider( 'mock2', 20, [ styleDef2 ] ).provider );
13
+ repo.register( createMockStylesProvider( { key: 'mock1', priority: 10, styleDefinitions: [ styleDef1 ] } ) );
14
+ repo.register( createMockStylesProvider( { key: 'mock2', priority: 20, styleDefinitions: [ styleDef2 ] } ) );
17
15
 
18
16
  // Assert
19
17
  expect( repo.all() ).toEqual( [ styleDef2, styleDef1 ] );
20
18
  } );
21
19
 
22
- it( 'should get all the style defs grouped by providers', () => {
23
- // Arrange
24
- const repo = createStylesRepository();
25
-
26
- repo.register( createMockProvider( 'mock1', 10, [ styleDef1 ] ).provider );
27
- repo.register( createMockProvider( 'mock2', 20, [ styleDef2, styleDef3 ] ).provider );
28
-
29
- // Assert
30
- expect( repo.allByProvider() ).toEqual( [
31
- [ expect.objectContaining( { key: 'mock2' } ), [ styleDef2, styleDef3 ] ],
32
- [ expect.objectContaining( { key: 'mock1' } ), [ styleDef1 ] ],
33
- ] );
34
- } );
35
-
36
20
  it( 'should subscribe and unsubscribe to all style providers', () => {
37
21
  // Arrange
38
22
  const repo = createStylesRepository();
39
23
 
40
- const { provider: mockStylesProvider1, notify: notify1 } = createMockProvider( 'mock1', 10, [ styleDef1 ] );
24
+ const mockStylesProvider1 = createMockStylesProvider( {
25
+ key: 'mock1',
26
+ priority: 10,
27
+ styleDefinitions: [ styleDef1 ],
28
+ } );
41
29
 
42
- const { provider: mockStylesProvider2, notify: notify2 } = createMockProvider( 'mock2', 10, [ styleDef2 ] );
30
+ const mockStylesProvider2 = createMockStylesProvider( {
31
+ key: 'mock2',
32
+ priority: 20,
33
+ styleDefinitions: [ styleDef2 ],
34
+ } );
43
35
 
44
36
  repo.register( mockStylesProvider1 );
45
37
  repo.register( mockStylesProvider2 );
@@ -47,6 +39,10 @@ describe( 'createStylesRepository', () => {
47
39
  const cb = jest.fn();
48
40
  const unsubscribe = repo.subscribe( cb );
49
41
 
42
+ // Force notifying the subscribers.
43
+ const notify1 = () => mockStylesProvider1.actions.update?.( {} as never );
44
+ const notify2 = () => mockStylesProvider2.actions.update?.( {} as never );
45
+
50
46
  // Act
51
47
  notify1();
52
48
 
@@ -68,29 +64,84 @@ describe( 'createStylesRepository', () => {
68
64
  // Assert
69
65
  expect( cb ).toHaveBeenCalledTimes( 2 );
70
66
  } );
71
- } );
72
67
 
73
- const createMockProvider = ( key: string, priority: number, styleDefinitions: StyleDefinition[] ) => {
74
- const subscribers = new Set< () => void >();
75
-
76
- const notify = () => {
77
- subscribers.forEach( ( cb ) => cb() );
78
- };
79
-
80
- const provider: StylesProvider = {
81
- key,
82
- priority,
83
- actions: {
84
- get: () => styleDefinitions,
85
- },
86
- subscribe: ( cb ) => {
87
- subscribers.add( cb );
88
-
89
- return () => {
90
- subscribers.delete( cb );
91
- };
92
- },
93
- };
94
-
95
- return { provider, notify };
96
- };
68
+ it( 'should return true if label is valid', () => {
69
+ // Arrange
70
+ const repo = createStylesRepository();
71
+
72
+ // Act
73
+ const result = repo.isLabelValid( 'valid-label' );
74
+
75
+ // Assert
76
+ expect( result ).toBe( true );
77
+ } );
78
+
79
+ it( 'should return false if label is not valid', () => {
80
+ // Arrange
81
+ const repo = createStylesRepository();
82
+
83
+ // Act
84
+ const result = repo.isLabelValid( '.invalid-label' );
85
+
86
+ // Assert
87
+ expect( result ).toBe( false );
88
+ } );
89
+
90
+ it( 'should return true if label is reserved', () => {
91
+ // Arrange
92
+ const repo = createStylesRepository();
93
+
94
+ const mockStylesProvider1 = createMockStylesProvider( {
95
+ key: 'mock1',
96
+ priority: 10,
97
+ styleDefinitions: [],
98
+ reservedLabel: 'reserved-label',
99
+ } );
100
+
101
+ repo.register( mockStylesProvider1 );
102
+
103
+ // Act
104
+ const result = repo.isLabelExist( 'reserved-label' );
105
+
106
+ // Assert
107
+ expect( result ).toBe( true );
108
+ } );
109
+
110
+ it( 'should return true if label exist', () => {
111
+ // Arrange
112
+ const repo = createStylesRepository();
113
+
114
+ const mockStylesProvider1 = createMockStylesProvider( {
115
+ key: 'mock1',
116
+ priority: 10,
117
+ styleDefinitions: [ styleDef1 ],
118
+ } );
119
+
120
+ repo.register( mockStylesProvider1 );
121
+
122
+ // Act
123
+ const result = repo.isLabelExist( styleDef1.label );
124
+
125
+ // Assert
126
+ expect( result ).toBe( true );
127
+ } );
128
+
129
+ it( 'should return false if label does not exist', () => {
130
+ // Arrange
131
+ const repo = createStylesRepository();
132
+
133
+ const mockStylesProvider1 = createMockStylesProvider( {
134
+ key: 'mock1',
135
+ priority: 10,
136
+ styleDefinitions: [],
137
+ } );
138
+
139
+ repo.register( mockStylesProvider1 );
140
+
141
+ // Act
142
+ const result = repo.isLabelExist( 'new-label' );
143
+
144
+ // Assert
145
+ expect( result ).toBe( false );
146
+ } );
147
+ } );
@@ -1,26 +1,40 @@
1
- import { type StyleDefinition } from '@elementor/editor-styles';
1
+ import { type Props } from '@elementor/editor-props';
2
+ import { type StyleDefinition, type StyleDefinitionID, type StyleDefinitionVariant } from '@elementor/editor-styles';
2
3
 
3
- export type MakeOptional< T, K extends keyof T > = Omit< T, K > & Partial< T >;
4
+ type MakeOptional< T, K extends keyof T > = Omit< T, K > & Partial< T >;
4
5
 
5
- export type GetActionPayload = Record< string, unknown >;
6
- export type CreateActionPayload = MakeOptional< StyleDefinition, 'id' | 'type' | 'variants' >;
7
6
  export type UpdateActionPayload = MakeOptional< StyleDefinition, 'label' | 'variants' | 'type' >;
8
7
 
8
+ export type UpdatePropsActionPayload = {
9
+ id: StyleDefinitionID;
10
+ meta: StyleDefinitionVariant[ 'meta' ];
11
+ props: Props;
12
+ };
13
+
14
+ export type Meta = Record< string, unknown >;
15
+
9
16
  export type StylesProvider = {
10
17
  key: string;
11
18
  priority: number;
12
19
  actions: {
13
- get: ( meta?: GetActionPayload ) => StyleDefinition[];
14
- create?: ( data: CreateActionPayload ) => Promise< StyleDefinition >;
15
- update?: ( data: UpdateActionPayload ) => Promise< StyleDefinition >;
20
+ get: ( meta?: Meta ) => StyleDefinition[];
21
+ getById: ( id: StyleDefinitionID, meta?: Meta ) => StyleDefinition | null;
22
+ create?: ( label: StyleDefinition[ 'label' ] ) => StyleDefinitionID;
23
+ delete?: ( id: StyleDefinitionID ) => void;
24
+ setOrder?: ( order: StyleDefinitionID[] ) => void;
25
+ update?: ( data: UpdateActionPayload ) => void;
26
+ updateProps?: ( args: UpdatePropsActionPayload, meta?: Meta ) => void;
16
27
  };
17
28
  subscribe: ( callback: () => void ) => () => void;
18
29
  labels?: {
19
30
  singular: string;
20
31
  plural: string;
21
32
  };
33
+ reservedLabel?: string;
22
34
  };
23
35
 
36
+ const VALID_SELECTOR_REGEX = /^[a-zA-Z0-9_-]+$/;
37
+
24
38
  export const createStylesRepository = () => {
25
39
  const providers: StylesProvider[] = [];
26
40
 
@@ -32,11 +46,7 @@ export const createStylesRepository = () => {
32
46
  providers.push( provider );
33
47
  };
34
48
 
35
- const allByProvider = ( meta: GetActionPayload = {} ) => {
36
- return getProviders().map( ( provider ) => [ provider, provider.actions.get( meta ) ] as const );
37
- };
38
-
39
- const all = ( meta: GetActionPayload = {} ) => {
49
+ const all = ( meta: Meta = {} ) => {
40
50
  return getProviders().flatMap( ( provider ) => provider.actions.get( meta ) );
41
51
  };
42
52
 
@@ -54,12 +64,30 @@ export const createStylesRepository = () => {
54
64
  return providers.find( ( provider ) => provider.key === key );
55
65
  };
56
66
 
67
+ const isLabelExist = ( newLabel: string ) => {
68
+ const classes = all();
69
+ const reservedLabels = providers.map( ( { reservedLabel } ) => reservedLabel ).filter( Boolean );
70
+
71
+ if ( reservedLabels.includes( newLabel ) ) {
72
+ return true;
73
+ }
74
+
75
+ if ( ! classes?.length ) {
76
+ return false;
77
+ }
78
+
79
+ return classes.some( ( { label } ) => label.toLowerCase() === newLabel.toLowerCase() );
80
+ };
81
+
82
+ const isLabelValid = ( newLabel: string ) => VALID_SELECTOR_REGEX.test( newLabel );
83
+
57
84
  return {
58
85
  all,
59
- allByProvider,
60
86
  register,
61
87
  subscribe,
62
88
  getProviders,
63
89
  getProviderByKey,
90
+ isLabelExist,
91
+ isLabelValid,
64
92
  };
65
93
  };