@elementor/editor-controls 4.4.0-1136 → 4.4.0-1138

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.mjs CHANGED
@@ -5664,7 +5664,7 @@ var AspectRatioControl = createControl(({ label }) => {
5664
5664
 
5665
5665
  // src/controls/svg-media-control.tsx
5666
5666
  import * as React92 from "react";
5667
- import { useEffect as useEffect17, useRef as useRef18, useState as useState21 } from "react";
5667
+ import { useEffect as useEffect17, useRef as useRef18, useState as useState22 } from "react";
5668
5668
  import { useCurrentUserCapabilities } from "@elementor/editor-current-user";
5669
5669
  import { iconPropTypeUtil, svgSrcPropTypeUtil, urlPropTypeUtil as urlPropTypeUtil4 } from "@elementor/editor-props";
5670
5670
  import { Box as Box23, Card as Card2, CardOverlay as CardOverlay2, Popover as Popover6, Stack as Stack18, styled as styled12, usePopupState as usePopupState9 } from "@elementor/ui";
@@ -5748,7 +5748,7 @@ function measureIconLibraryAnchor(container, buttonGroup) {
5748
5748
 
5749
5749
  // src/controls/icon-library/icon-library-popover.tsx
5750
5750
  import * as React89 from "react";
5751
- import { useMemo as useMemo12, useState as useState20 } from "react";
5751
+ import { useMemo as useMemo12, useState as useState21 } from "react";
5752
5752
  import {
5753
5753
  PopoverBody as PopoverBody2,
5754
5754
  PopoverHeader as PopoverHeader4,
@@ -5762,599 +5762,6 @@ import { Box as Box20, CircularProgress as CircularProgress3, Divider as Divider
5762
5762
  import { useDebounceState } from "@elementor/utils";
5763
5763
  import { __ as __37 } from "@wordpress/i18n";
5764
5764
 
5765
- // src/controls/icon-library/custom-icon-libraries.ts
5766
- import { httpService as httpService3 } from "@elementor/http-client";
5767
- import { useQuery as useQuery2 } from "@elementor/query";
5768
-
5769
- // src/controls/open-icon-library.ts
5770
- import { stringPropTypeUtil as stringPropTypeUtil14 } from "@elementor/editor-props";
5771
- function enqueueIconFonts(library) {
5772
- window.elementor?.helpers?.enqueueIconFonts?.(library);
5773
- }
5774
- function createIconPropValue(icon, library) {
5775
- return {
5776
- value: stringPropTypeUtil14.create(icon),
5777
- library: stringPropTypeUtil14.create(library)
5778
- };
5779
- }
5780
-
5781
- // src/controls/icon-library/fontello-svg-font.ts
5782
- function parseFontelloSvgFont(configJson, svgFont, prefix, displayPrefix, iconNames) {
5783
- const codepoints = parseConfigCodepoints(configJson, prefix);
5784
- const configPaths = parseConfigSvgPaths(configJson, prefix);
5785
- const glyphs = parseSvgFontGlyphs(svgFont);
5786
- const resolvedDisplayPrefix = displayPrefix || prefix.replace(/-$/, "");
5787
- const result = {};
5788
- for (const name of iconNames) {
5789
- const fromConfig = configPaths.get(name) ?? (prefix && name.startsWith(prefix) ? configPaths.get(name.slice(prefix.length)) : void 0);
5790
- const glyph = fromConfig ?? findGlyph(glyphs, codepoints, name, prefix);
5791
- if (!glyph) {
5792
- continue;
5793
- }
5794
- const value = `${resolvedDisplayPrefix} ${prefix}${name}`.trim();
5795
- result[value] = buildIconSvg(glyph);
5796
- }
5797
- return result;
5798
- }
5799
- function parseConfigCodepoints(configJson, prefix) {
5800
- const map = /* @__PURE__ */ new Map();
5801
- try {
5802
- const data = JSON.parse(configJson);
5803
- if (!Array.isArray(data.glyphs)) {
5804
- return map;
5805
- }
5806
- for (const glyph of data.glyphs) {
5807
- if (typeof glyph.css !== "string" || glyph.css === "" || typeof glyph.code !== "number") {
5808
- continue;
5809
- }
5810
- map.set(glyph.css, glyph.code);
5811
- if (prefix !== "" && !glyph.css.startsWith(prefix)) {
5812
- map.set(`${prefix}${glyph.css}`, glyph.code);
5813
- }
5814
- }
5815
- } catch {
5816
- return map;
5817
- }
5818
- return map;
5819
- }
5820
- function parseConfigSvgPaths(configJson, prefix) {
5821
- const map = /* @__PURE__ */ new Map();
5822
- try {
5823
- const data = JSON.parse(configJson);
5824
- if (!Array.isArray(data.glyphs)) {
5825
- return map;
5826
- }
5827
- for (const glyph of data.glyphs) {
5828
- if (typeof glyph.css !== "string" || glyph.css === "") {
5829
- continue;
5830
- }
5831
- let path = "";
5832
- let advance = 1e3;
5833
- if (typeof glyph.svg === "string") {
5834
- path = glyph.svg;
5835
- } else if (glyph.svg && typeof glyph.svg === "object" && "path" in glyph.svg && typeof glyph.svg.path === "string") {
5836
- path = glyph.svg.path;
5837
- if ("width" in glyph.svg && typeof glyph.svg.width === "number" && glyph.svg.width > 0) {
5838
- advance = glyph.svg.width;
5839
- }
5840
- }
5841
- if (path === "") {
5842
- continue;
5843
- }
5844
- const record = { d: path, units: 1e3, advance };
5845
- map.set(glyph.css, record);
5846
- if (prefix !== "" && !glyph.css.startsWith(prefix)) {
5847
- map.set(`${prefix}${glyph.css}`, record);
5848
- }
5849
- }
5850
- } catch {
5851
- return map;
5852
- }
5853
- return map;
5854
- }
5855
- function parseSvgFontGlyphs(svgFont) {
5856
- const byName = /* @__PURE__ */ new Map();
5857
- const byCode = /* @__PURE__ */ new Map();
5858
- const doc = new DOMParser().parseFromString(stripDoctype(svgFont), "image/svg+xml");
5859
- const font = doc.querySelector("font");
5860
- const face = doc.querySelector("font-face");
5861
- const fontAdvance = positiveInt(font?.getAttribute("horiz-adv-x"), 1e3);
5862
- const units2 = positiveInt(face?.getAttribute("units-per-em"), fontAdvance);
5863
- doc.querySelectorAll("glyph").forEach((node) => {
5864
- const d = node.getAttribute("d") ?? "";
5865
- if (d === "") {
5866
- return;
5867
- }
5868
- const record = {
5869
- d,
5870
- units: units2,
5871
- advance: positiveInt(node.getAttribute("horiz-adv-x"), fontAdvance)
5872
- };
5873
- const name = node.getAttribute("glyph-name") ?? "";
5874
- const unicode = node.getAttribute("unicode") ?? "";
5875
- const code = unicode.codePointAt(0);
5876
- if (name) {
5877
- byName.set(name, record);
5878
- }
5879
- if (code !== void 0) {
5880
- byCode.set(code, record);
5881
- }
5882
- });
5883
- return { byName, byCode };
5884
- }
5885
- function findGlyph(glyphs, codepoints, iconName, prefix) {
5886
- const names = [iconName];
5887
- if (prefix !== "" && iconName.startsWith(prefix)) {
5888
- names.push(iconName.slice(prefix.length));
5889
- }
5890
- for (const name of names) {
5891
- const byName = glyphs.byName.get(name);
5892
- if (byName) {
5893
- return byName;
5894
- }
5895
- const code = codepoints.get(name);
5896
- const byCode = code !== void 0 ? glyphs.byCode.get(code) : void 0;
5897
- if (byCode) {
5898
- return byCode;
5899
- }
5900
- }
5901
- return null;
5902
- }
5903
- function buildIconSvg(glyph) {
5904
- return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${glyph.advance} ${glyph.units}" fill="currentColor" width="100%" height="100%"><g transform="translate(0,${glyph.units}) scale(1,-1)"><path d="${escapeAttribute(glyph.d)}" fill="currentColor"></path></g></svg>`;
5905
- }
5906
- function stripDoctype(svgFont) {
5907
- return svgFont.replace(/<!DOCTYPE[^>]*>/is, "");
5908
- }
5909
- function positiveInt(value, fallback) {
5910
- if (!value) {
5911
- return fallback;
5912
- }
5913
- const parsed = Number.parseInt(value, 10);
5914
- return parsed > 0 ? parsed : fallback;
5915
- }
5916
- function escapeAttribute(value) {
5917
- return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5918
- }
5919
-
5920
- // src/controls/icon-library/icomoon-selection.ts
5921
- var DEFAULT_ICOMOON_VIEWBOX = 1024;
5922
- function parseIcomoonSelection(selectionJson, prefix, displayPrefix, iconNames) {
5923
- let data;
5924
- try {
5925
- data = JSON.parse(selectionJson);
5926
- } catch {
5927
- return {};
5928
- }
5929
- const resolvedDisplayPrefix = displayPrefix || prefix.replace(/-$/, "");
5930
- const names = iconNames.length > 0 ? iconNames : namesFromSelection(data);
5931
- const result = {};
5932
- for (const name of names) {
5933
- const markup = svgForName(data, name, prefix);
5934
- if (!markup) {
5935
- continue;
5936
- }
5937
- result[`${resolvedDisplayPrefix} ${prefix}${name}`.trim()] = markup;
5938
- }
5939
- return result;
5940
- }
5941
- function namesFromSelection(data) {
5942
- if (!Array.isArray(data.icons)) {
5943
- return [];
5944
- }
5945
- return data.icons.flatMap((icon) => {
5946
- const name = iconEntryName(icon);
5947
- return name ? [name] : [];
5948
- });
5949
- }
5950
- function svgForName(data, iconName, prefix) {
5951
- const candidates = [iconName];
5952
- if (prefix && iconName.startsWith(prefix)) {
5953
- candidates.push(iconName.slice(prefix.length));
5954
- }
5955
- for (const icon of data.icons ?? []) {
5956
- const name = iconEntryName(icon);
5957
- if (!name || !candidates.includes(name)) {
5958
- continue;
5959
- }
5960
- const paths = Array.isArray(icon.icon?.paths) ? icon.icon.paths.filter((path) => typeof path === "string" && path !== "") : [];
5961
- if (paths.length === 0) {
5962
- return null;
5963
- }
5964
- const size = typeof icon.icon?.width === "number" && icon.icon.width > 0 ? icon.icon.width : DEFAULT_ICOMOON_VIEWBOX;
5965
- const pathMarkup = paths.map((d) => `<path d="${escapeAttribute2(d)}" fill="currentColor"></path>`).join("");
5966
- return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" fill="currentColor" width="100%" height="100%">` + pathMarkup + "</svg>";
5967
- }
5968
- return null;
5969
- }
5970
- function iconEntryName(icon) {
5971
- if (typeof icon.properties?.name === "string") {
5972
- return icon.properties.name;
5973
- }
5974
- const tag = icon.icon?.tags;
5975
- return Array.isArray(tag) && typeof tag[0] === "string" ? tag[0] : "";
5976
- }
5977
- function escapeAttribute2(value) {
5978
- return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
5979
- }
5980
-
5981
- // src/controls/icon-library/custom-icon-libraries.ts
5982
- var NATIVE_TAB_NAMES = /* @__PURE__ */ new Set(["all", "recommended", "GoPro"]);
5983
- var DEFAULT_ICON_SIZE = 512;
5984
- var CUSTOM_ICON_LIBRARIES_QUERY_KEY = ["custom-icon-libraries"];
5985
- var CUSTOM_ICON_SVG_URL = "elementor/v1/atomic-widgets/custom-icon-svg";
5986
- var SUPPORTED_CUSTOM_ICON_TYPES = /* @__PURE__ */ new Set(["fontello", "icomoon", "fontastic"]);
5987
- var svgMapCache = /* @__PURE__ */ new Map();
5988
- var inFlightSvgMaps = /* @__PURE__ */ new Map();
5989
- function isDeletedCustomIconLibrary(library, iconValue) {
5990
- const libraryName = String(library);
5991
- if (!libraryName || !iconValue) {
5992
- return false;
5993
- }
5994
- if (NATIVE_TAB_NAMES.has(libraryName) || libraryName.startsWith("fa-")) {
5995
- return false;
5996
- }
5997
- return !getCustomIconLibraryConfigs().some((item) => item.name === libraryName);
5998
- }
5999
- function useCustomIconLibraries(enabled) {
6000
- return useQuery2({
6001
- queryKey: CUSTOM_ICON_LIBRARIES_QUERY_KEY,
6002
- queryFn: ({ signal }) => loadCustomIconLibraries(signal),
6003
- enabled: enabled && areCustomIconLibrariesEnabled(),
6004
- staleTime: Infinity
6005
- });
6006
- }
6007
- async function loadCustomIconLibraries(signal) {
6008
- const catalogs = await Promise.all(
6009
- getCustomIconLibraryConfigs().map((library) => loadCustomLibrary(library, signal))
6010
- );
6011
- return catalogs.flat();
6012
- }
6013
- async function resolveCustomIconSvg(library, iconValue, signal) {
6014
- const config = getCustomIconLibraryConfigs().find((item) => item.name === String(library));
6015
- if (!config) {
6016
- svgMapCache.delete(String(library));
6017
- return null;
6018
- }
6019
- const map = await loadLibrarySvgMap(String(library), config, signal);
6020
- const markup = map[iconValue];
6021
- return typeof markup === "string" && markup !== "" ? markup : null;
6022
- }
6023
- function areCustomIconLibrariesEnabled() {
6024
- return true === window.elementorCommon?.config?.fontAwesome?.v7?.customIconLibrariesEnabled;
6025
- }
6026
- function getCustomIconLibraryConfigs() {
6027
- if (!areCustomIconLibrariesEnabled()) {
6028
- return [];
6029
- }
6030
- const libraries = window.elementor?.config;
6031
- const items2 = Array.isArray(libraries?.icons?.libraries) ? libraries.icons.libraries : [];
6032
- return items2.flatMap((value) => {
6033
- const library = normalizeCustomIconLibraryConfig(value);
6034
- return library ? [library] : [];
6035
- });
6036
- }
6037
- function normalizeCustomIconLibraryConfig(value) {
6038
- if (!value || typeof value !== "object") {
6039
- return null;
6040
- }
6041
- const library = value;
6042
- const name = coerceLibraryName(library.name);
6043
- if (name === "" || NATIVE_TAB_NAMES.has(name) || library.native === true || name.startsWith("fa-")) {
6044
- return null;
6045
- }
6046
- if (typeof library.prefix !== "string") {
6047
- return null;
6048
- }
6049
- if (!library.fetchJson && library.icons === void 0) {
6050
- return null;
6051
- }
6052
- const resolved = {
6053
- ...library,
6054
- name,
6055
- prefix: library.prefix,
6056
- ...getPackUrls(name, library)
6057
- };
6058
- if (!resolveCustomIconType(resolved)) {
6059
- return null;
6060
- }
6061
- return resolved;
6062
- }
6063
- function coerceLibraryName(value) {
6064
- if (typeof value === "string") {
6065
- return value;
6066
- }
6067
- if (typeof value === "number" && Number.isFinite(value)) {
6068
- return String(value);
6069
- }
6070
- return "";
6071
- }
6072
- function getPackUrls(library, config) {
6073
- const derived = derivePackAssetUrls(config.fetchJson, resolveCustomIconType(config));
6074
- const packs = window.elementorCommon?.config?.fontAwesome?.v7?.customIconPacks;
6075
- if (!packs || typeof packs !== "object") {
6076
- return derived;
6077
- }
6078
- const pack = packs[library];
6079
- if (!pack || typeof pack !== "object") {
6080
- return derived;
6081
- }
6082
- const packType = typeof pack.type === "string" ? pack.type : config.custom_icon_type;
6083
- return {
6084
- ...derived,
6085
- configUrl: typeof pack.configUrl === "string" ? pack.configUrl : derived.configUrl,
6086
- fontUrl: typeof pack.fontUrl === "string" ? pack.fontUrl : derived.fontUrl,
6087
- selectionUrl: typeof pack.selectionUrl === "string" ? pack.selectionUrl : derived.selectionUrl,
6088
- custom_icon_type: packType ?? derived.custom_icon_type
6089
- };
6090
- }
6091
- function resolveCustomIconType(library) {
6092
- const type = typeof library.custom_icon_type === "string" ? library.custom_icon_type.toLowerCase() : "";
6093
- return SUPPORTED_CUSTOM_ICON_TYPES.has(type) ? type : "";
6094
- }
6095
- function derivePackAssetUrls(fetchJson, type) {
6096
- if (!fetchJson) {
6097
- return type ? { custom_icon_type: type } : {};
6098
- }
6099
- try {
6100
- const url = new URL(fetchJson, window.location.origin);
6101
- const base = url.href.replace(/\/[^/?#]+(?:\?.*)?$/, "");
6102
- if ("icomoon" === type) {
6103
- return {
6104
- custom_icon_type: type,
6105
- selectionUrl: `${base}/selection.json`,
6106
- fontUrl: `${base}/fonts/icomoon.svg`
6107
- };
6108
- }
6109
- if ("fontastic" === type) {
6110
- return {
6111
- custom_icon_type: type,
6112
- fontUrl: `${base}/fonts/fontastic.svg`
6113
- };
6114
- }
6115
- if ("fontello" === type) {
6116
- return {
6117
- custom_icon_type: type,
6118
- configUrl: `${base}/config.json`,
6119
- fontUrl: `${base}/font/fontello.svg`
6120
- };
6121
- }
6122
- return {};
6123
- } catch {
6124
- return type ? { custom_icon_type: type } : {};
6125
- }
6126
- }
6127
- async function loadCustomLibrary(library, signal) {
6128
- enqueueIconFonts(library.name);
6129
- const names = parseIconNames(await loadLibraryPayload(library, signal));
6130
- const svgMap = await loadLibrarySvgMap(library.name, library, signal);
6131
- return names.map((name) => {
6132
- const value = createCustomIconSelectionValue(library, name);
6133
- return {
6134
- id: `${library.name}:${name}`,
6135
- name,
6136
- label: name.replace(/-/g, " "),
6137
- library: library.name,
6138
- value,
6139
- aliases: [],
6140
- width: DEFAULT_ICON_SIZE,
6141
- height: DEFAULT_ICON_SIZE,
6142
- paths: [],
6143
- glyphClass: value,
6144
- svgMarkup: svgMap[value]
6145
- };
6146
- });
6147
- }
6148
- async function loadLibrarySvgMap(library, config, signal) {
6149
- if (!config) {
6150
- svgMapCache.delete(library);
6151
- inFlightSvgMaps.delete(library);
6152
- return {};
6153
- }
6154
- const cached = svgMapCache.get(library);
6155
- if (cached && Object.keys(cached).length > 0) {
6156
- return cached;
6157
- }
6158
- const pending = inFlightSvgMaps.get(library);
6159
- if (pending) {
6160
- return pending;
6161
- }
6162
- const request = fetchLibrarySvgMap(library, config, signal).finally(() => {
6163
- inFlightSvgMaps.delete(library);
6164
- });
6165
- inFlightSvgMaps.set(library, request);
6166
- return request;
6167
- }
6168
- async function fetchLibrarySvgMap(library, config, signal) {
6169
- const fromRest = await loadSvgMapFromRest(library, signal);
6170
- const restIcons = fromRest.icons;
6171
- if (Object.keys(restIcons).length > 0 && !fromRest.truncated) {
6172
- svgMapCache.set(library, restIcons);
6173
- return restIcons;
6174
- }
6175
- const fromPack = await loadSvgMapFromPackFiles(config, signal);
6176
- const merged = { ...fromPack, ...restIcons };
6177
- if (Object.keys(merged).length > 0) {
6178
- svgMapCache.set(library, merged);
6179
- return merged;
6180
- }
6181
- return {};
6182
- }
6183
- async function loadSvgMapFromRest(library, signal) {
6184
- try {
6185
- const response = await httpService3().get(CUSTOM_ICON_SVG_URL, { params: { library: String(library) }, signal });
6186
- return unwrapIconMap(response);
6187
- } catch {
6188
- return { icons: {}, truncated: false };
6189
- }
6190
- }
6191
- function unwrapIconMap(payload) {
6192
- let current = payload;
6193
- for (let depth = 0; depth < 4; depth++) {
6194
- if (!current || typeof current !== "object") {
6195
- return { icons: {}, truncated: false };
6196
- }
6197
- const record = current;
6198
- if (record.icons && typeof record.icons === "object" && !Array.isArray(record.icons)) {
6199
- const icons = {};
6200
- Object.entries(record.icons).forEach(([key, value]) => {
6201
- if (typeof value === "string" && value !== "") {
6202
- icons[key] = value;
6203
- }
6204
- });
6205
- return {
6206
- icons,
6207
- truncated: true === record.truncated
6208
- };
6209
- }
6210
- current = "data" in record ? record.data : void 0;
6211
- }
6212
- return { icons: {}, truncated: false };
6213
- }
6214
- async function loadSvgMapFromPackFiles(library, signal) {
6215
- const type = resolveCustomIconType(library);
6216
- if (!type) {
6217
- return {};
6218
- }
6219
- if ("icomoon" === type && library.selectionUrl) {
6220
- try {
6221
- const response = await fetch(library.selectionUrl, { signal, mode: "cors" });
6222
- if (response.ok) {
6223
- const selectionJson = await response.text();
6224
- const names2 = parseIconNames(safeJson(selectionJson));
6225
- const payloadNames2 = names2.length > 0 ? names2 : parseIconNames({ icons: library.icons });
6226
- const fromSelection = parseIcomoonSelection(
6227
- selectionJson,
6228
- library.prefix,
6229
- library.displayPrefix ?? "",
6230
- payloadNames2
6231
- );
6232
- if (Object.keys(fromSelection).length > 0) {
6233
- return fromSelection;
6234
- }
6235
- }
6236
- } catch {
6237
- }
6238
- }
6239
- const fontUrls = uniqueUrls([
6240
- library.fontUrl,
6241
- "fontello" === type && library.fetchJson ? packSiblingUrl(library.fetchJson, "font/fontello.svg") : null,
6242
- "fontastic" === type && library.fetchJson ? packSiblingUrl(library.fetchJson, "fonts/fontastic.svg") : null,
6243
- "icomoon" === type && library.fetchJson ? packSiblingUrl(library.fetchJson, "fonts/icomoon.svg") : null
6244
- ]);
6245
- if (fontUrls.length === 0) {
6246
- return {};
6247
- }
6248
- let configJson = "{}";
6249
- if (library.configUrl) {
6250
- try {
6251
- const configResponse = await fetch(library.configUrl, { signal, mode: "cors" });
6252
- if (configResponse.ok) {
6253
- configJson = await configResponse.text();
6254
- }
6255
- } catch {
6256
- configJson = "{}";
6257
- }
6258
- }
6259
- const names = parseIconNames(safeJson(configJson));
6260
- const payloadNames = names.length > 0 ? names : parseIconNames({ icons: library.icons });
6261
- for (const fontUrl of fontUrls) {
6262
- try {
6263
- const fontResponse = await fetch(fontUrl, { signal, mode: "cors" });
6264
- if (!fontResponse.ok) {
6265
- continue;
6266
- }
6267
- const fromFont = parseFontelloSvgFont(
6268
- configJson,
6269
- await fontResponse.text(),
6270
- library.prefix,
6271
- library.displayPrefix ?? "",
6272
- payloadNames
6273
- );
6274
- if (Object.keys(fromFont).length > 0) {
6275
- return fromFont;
6276
- }
6277
- } catch {
6278
- continue;
6279
- }
6280
- }
6281
- return {};
6282
- }
6283
- function packSiblingUrl(fetchJson, relativePath) {
6284
- try {
6285
- const url = new URL(fetchJson, window.location.origin);
6286
- url.pathname = url.pathname.replace(/\/[^/]+$/, `/${relativePath}`);
6287
- return url.href;
6288
- } catch {
6289
- return null;
6290
- }
6291
- }
6292
- function uniqueUrls(urls) {
6293
- return [...new Set(urls.filter((url) => typeof url === "string" && url !== ""))];
6294
- }
6295
- function safeJson(value) {
6296
- try {
6297
- return JSON.parse(value);
6298
- } catch {
6299
- return null;
6300
- }
6301
- }
6302
- async function loadLibraryPayload(library, signal) {
6303
- if (library.icons !== void 0) {
6304
- return { icons: library.icons };
6305
- }
6306
- if (!library.fetchJson) {
6307
- return null;
6308
- }
6309
- try {
6310
- const response = await fetch(library.fetchJson, { signal, mode: "cors" });
6311
- return response.ok ? response.json() : null;
6312
- } catch {
6313
- return null;
6314
- }
6315
- }
6316
- function parseIconNames(payload) {
6317
- if (!payload || typeof payload !== "object") {
6318
- return [];
6319
- }
6320
- const icons = payload.icons;
6321
- if (Array.isArray(icons)) {
6322
- return icons.flatMap((entry) => {
6323
- if (typeof entry === "string") {
6324
- return [normalizeIconName(entry)];
6325
- }
6326
- if (entry && typeof entry === "object" && "name" in entry && typeof entry.name === "string") {
6327
- return [normalizeIconName(entry.name)];
6328
- }
6329
- if (entry && typeof entry === "object" && "properties" in entry && entry.properties && typeof entry.properties === "object" && "name" in entry.properties && typeof entry.properties.name === "string") {
6330
- return [normalizeIconName(entry.properties.name)];
6331
- }
6332
- return [];
6333
- }).filter(Boolean);
6334
- }
6335
- if (icons && typeof icons === "object") {
6336
- return Object.keys(icons).map(normalizeIconName).filter(Boolean);
6337
- }
6338
- const glyphs = payload.glyphs;
6339
- if (Array.isArray(glyphs)) {
6340
- return glyphs.flatMap((entry) => {
6341
- if (entry && typeof entry === "object" && "css" in entry && typeof entry.css === "string") {
6342
- return [normalizeIconName(entry.css)];
6343
- }
6344
- return [];
6345
- }).filter(Boolean);
6346
- }
6347
- return [];
6348
- }
6349
- function normalizeIconName(name) {
6350
- return name.trim().replace(/^:/, "").replace(/:$/, "");
6351
- }
6352
- function createCustomIconSelectionValue(library, name) {
6353
- const prefix = library.prefix;
6354
- const displayPrefix = library.displayPrefix || prefix.replace(/-$/, "");
6355
- return `${displayPrefix} ${prefix}${name}`.trim();
6356
- }
6357
-
6358
5765
  // src/controls/icon-library/font-awesome-7-data.ts
6359
5766
  var FONT_AWESOME_7_LIBRARIES = [
6360
5767
  { file: "solid", library: "fa-solid" },
@@ -7202,6 +6609,39 @@ var IconLibraryGrid = ({
7202
6609
  );
7203
6610
  };
7204
6611
 
6612
+ // src/controls/icon-library/icon-library-providers.ts
6613
+ import { useState as useState20 } from "react";
6614
+ var providers = /* @__PURE__ */ new Map();
6615
+ function registerIconLibraryProvider(provider) {
6616
+ providers.set(provider.id, provider);
6617
+ }
6618
+ function unregisterIconLibraryProvider(id) {
6619
+ providers.delete(id);
6620
+ }
6621
+ function useIconLibraryProviderIcons(enabled) {
6622
+ const [snapshot] = useState20(() => [...providers.values()]);
6623
+ const states = snapshot.map((provider) => provider.useIcons(enabled));
6624
+ return {
6625
+ data: states.flatMap((state) => state.data ?? []),
6626
+ isLoading: states.some((state) => state.isLoading)
6627
+ };
6628
+ }
6629
+ async function resolveProviderIconSvg(library, iconValue, signal) {
6630
+ for (const provider of providers.values()) {
6631
+ try {
6632
+ const markup = await provider.resolveSvg?.(library, iconValue, signal);
6633
+ if (markup) {
6634
+ return markup;
6635
+ }
6636
+ } catch (error) {
6637
+ if (signal?.aborted) {
6638
+ throw error;
6639
+ }
6640
+ }
6641
+ }
6642
+ return null;
6643
+ }
6644
+
7205
6645
  // src/controls/icon-library/icon-library-view-toggle.tsx
7206
6646
  import * as React87 from "react";
7207
6647
  import { ListIcon, WidgetsIcon } from "@elementor/icons";
@@ -7245,10 +6685,10 @@ var SvgElementIcon = React88.forwardRef(
7245
6685
  );
7246
6686
 
7247
6687
  // src/controls/icon-library/use-font-awesome-7-catalog.ts
7248
- import { useQuery as useQuery3 } from "@elementor/query";
6688
+ import { useQuery as useQuery2 } from "@elementor/query";
7249
6689
  var FONT_AWESOME_7_CATALOG_QUERY_KEY = ["font-awesome-7-catalog"];
7250
6690
  function useFontAwesome7Catalog(enabled) {
7251
- return useQuery3({
6691
+ return useQuery2({
7252
6692
  queryKey: FONT_AWESOME_7_CATALOG_QUERY_KEY,
7253
6693
  queryFn: ({ signal }) => loadFontAwesome7Catalog(signal),
7254
6694
  enabled,
@@ -7292,16 +6732,16 @@ var IconLibraryPopover = ({
7292
6732
  handleChange: handleSearchChange,
7293
6733
  setImmediateValue: setSearchValue
7294
6734
  } = useDebounceState({ delay: ICON_LIBRARY_SEARCH_DEBOUNCE_DELAY });
7295
- const [activeLibraries, setActiveLibraries] = useState20([]);
6735
+ const [activeLibraries, setActiveLibraries] = useState21([]);
7296
6736
  const [storedView, setStoredView] = useSessionStorage2(
7297
6737
  ICON_LIBRARY_VIEW_STORAGE_KEY,
7298
6738
  ICON_LIBRARY_VIEW_STORAGE_PREFIX
7299
6739
  );
7300
6740
  const view = isIconLibraryView(storedView) ? storedView : DEFAULT_ICON_LIBRARY_VIEW;
7301
6741
  const { data: fontAwesomeIcons = [], isLoading: isFontAwesomeLoading } = useFontAwesome7Catalog(open);
7302
- const { data: customIcons = [], isLoading: isCustomLoading } = useCustomIconLibraries(open);
7303
- const isLoading = isFontAwesomeLoading || isCustomLoading;
7304
- const icons = useMemo12(() => [...fontAwesomeIcons, ...customIcons], [customIcons, fontAwesomeIcons]);
6742
+ const { data: providerIcons = [], isLoading: isProviderLoading } = useIconLibraryProviderIcons(open);
6743
+ const isLoading = isFontAwesomeLoading || isProviderLoading;
6744
+ const icons = useMemo12(() => [...fontAwesomeIcons, ...providerIcons], [providerIcons, fontAwesomeIcons]);
7305
6745
  const items2 = useMemo12(
7306
6746
  () => createIconLibraryItems(icons, searchValue, activeLibraries),
7307
6747
  [activeLibraries, icons, searchValue]
@@ -7464,6 +6904,18 @@ var createIconLibraryItems = (icons, searchValue, libraries) => filterFontAwesom
7464
6904
  value: icon.id
7465
6905
  }));
7466
6906
 
6907
+ // src/controls/open-icon-library.ts
6908
+ import { stringPropTypeUtil as stringPropTypeUtil14 } from "@elementor/editor-props";
6909
+ function enqueueIconFonts(library) {
6910
+ window.elementor?.helpers?.enqueueIconFonts?.(library);
6911
+ }
6912
+ function createIconPropValue(icon, library) {
6913
+ return {
6914
+ value: stringPropTypeUtil14.create(icon),
6915
+ library: stringPropTypeUtil14.create(library)
6916
+ };
6917
+ }
6918
+
7467
6919
  // src/controls/svg-media-overlay.tsx
7468
6920
  import * as React90 from "react";
7469
6921
  import { LibraryIcon as LibraryIcon3 } from "@elementor/icons";
@@ -7532,10 +6984,10 @@ var ICON_PREVIEW_COLOR = "#000000";
7532
6984
  var SvgMediaPreview = ({ isFetching, src, iconClassName, iconLibrary }) => {
7533
6985
  const shouldLoadIconCatalog = Boolean(iconClassName && iconLibrary);
7534
6986
  const { data: fontAwesomeIcons = [], isLoading: isFontAwesomeLoading } = useFontAwesome7Catalog(shouldLoadIconCatalog);
7535
- const { data: customIcons = [], isLoading: isCustomLoading } = useCustomIconLibraries(shouldLoadIconCatalog);
7536
- const icons = [...fontAwesomeIcons, ...customIcons];
6987
+ const { data: providerIcons = [], isLoading: isProviderLoading } = useIconLibraryProviderIcons(shouldLoadIconCatalog);
6988
+ const icons = [...fontAwesomeIcons, ...providerIcons];
7537
6989
  const selectedIcon = findFontAwesome7Icon(icons, iconClassName, iconLibrary);
7538
- const isLoadingCatalog = shouldLoadIconCatalog && (isFontAwesomeLoading || isCustomLoading);
6990
+ const isLoadingCatalog = shouldLoadIconCatalog && (isFontAwesomeLoading || isProviderLoading);
7539
6991
  if (isFetching || isLoadingCatalog) {
7540
6992
  return /* @__PURE__ */ React91.createElement(CircularProgress4, { role: "progressbar" });
7541
6993
  }
@@ -7607,21 +7059,23 @@ var MODE_BROWSE = { mode: "browse" };
7607
7059
  var MODE_UPLOAD = { mode: "upload" };
7608
7060
  var SvgMediaControl = createControl(({ showIconLibrary = false, label }) => {
7609
7061
  const groupLabel = label ?? __40("SVG", "elementor");
7610
- const { value: svgValue, setValue: setSvgValue } = useBoundProp(svgSrcPropTypeUtil);
7611
- const { value: iconValue, setValue: setIconValue } = useBoundProp(iconPropTypeUtil);
7062
+ const { value: svgValue, setValue: setSvgValue, placeholder: svgPlaceholder } = useBoundProp(svgSrcPropTypeUtil);
7063
+ const { value: iconValue, setValue: setIconValue, placeholder: iconPlaceholder } = useBoundProp(iconPropTypeUtil);
7612
7064
  const id = svgValue?.id;
7613
- const url = svgValue?.url;
7614
- const { data: attachment, isFetching } = useWpMediaAttachment2(id?.value || null);
7615
- const src = attachment?.url ?? url?.value ?? null;
7065
+ const hasOwnValue = svgValue !== null && svgValue !== void 0 || iconValue !== null && iconValue !== void 0;
7066
+ const previewSvgValue = hasOwnValue ? svgValue : svgPlaceholder;
7067
+ const previewIconValue = hasOwnValue ? iconValue : iconPlaceholder;
7068
+ const { data: attachment, isFetching } = useWpMediaAttachment2(previewSvgValue?.id?.value || null);
7069
+ const src = attachment?.url ?? previewSvgValue?.url?.value ?? null;
7616
7070
  const { data: allowSvgUpload } = useUnfilteredFilesUpload();
7617
- const [unfilteredModalOpenState, setUnfilteredModalOpenState] = useState21(false);
7071
+ const [unfilteredModalOpenState, setUnfilteredModalOpenState] = useState22(false);
7618
7072
  const iconLibraryPopoverState = usePopupState9({ variant: "popover" });
7619
7073
  const controlContainerRef = useRef18(null);
7620
7074
  const buttonGroupRef = useRef18(null);
7621
- const [iconLibraryAnchor, setIconLibraryAnchor] = useState21(null);
7075
+ const [iconLibraryAnchor, setIconLibraryAnchor] = useState22(null);
7622
7076
  const { isAdmin } = useCurrentUserCapabilities();
7623
- const selectedIconClass = showIconLibrary && typeof iconValue?.value?.value === "string" ? iconValue.value.value : null;
7624
- const selectedIconLibrary = showIconLibrary && typeof iconValue?.library?.value === "string" ? iconValue.library.value : null;
7077
+ const selectedIconClass = showIconLibrary && typeof previewIconValue?.value?.value === "string" ? previewIconValue.value.value : null;
7078
+ const selectedIconLibrary = showIconLibrary && typeof previewIconValue?.library?.value === "string" ? previewIconValue.library.value : null;
7625
7079
  const { open } = useWpMediaFrame2({
7626
7080
  mediaTypes: ["svg"],
7627
7081
  multiple: false,
@@ -8565,7 +8019,7 @@ var getAllProperties = (pattern) => {
8565
8019
 
8566
8020
  // src/controls/key-value-control.tsx
8567
8021
  import * as React102 from "react";
8568
- import { useMemo as useMemo14, useState as useState22 } from "react";
8022
+ import { useMemo as useMemo14, useState as useState23 } from "react";
8569
8023
  import {
8570
8024
  isTransformable,
8571
8025
  keyValuePropTypeUtil,
@@ -8596,9 +8050,9 @@ var getInitialFieldValue = (fieldValue) => {
8596
8050
  };
8597
8051
  var KeyValueControl = createControl((props = {}) => {
8598
8052
  const { value, setValue, ...propContext } = useBoundProp(keyValuePropTypeUtil);
8599
- const [keyError, setKeyError] = useState22("");
8600
- const [valueError, setValueError] = useState22("");
8601
- const [sessionState, setSessionState] = useState22({
8053
+ const [keyError, setKeyError] = useState23("");
8054
+ const [valueError, setValueError] = useState23("");
8055
+ const [sessionState, setSessionState] = useState23({
8602
8056
  key: getInitialFieldValue(value?.key),
8603
8057
  value: getInitialFieldValue(value?.value)
8604
8058
  });
@@ -9347,7 +8801,7 @@ var TransformBasePopoverTrigger = ({
9347
8801
 
9348
8802
  // src/controls/transition-control/transition-repeater-control.tsx
9349
8803
  import * as React119 from "react";
9350
- import { useEffect as useEffect18, useMemo as useMemo17, useState as useState23 } from "react";
8804
+ import { useEffect as useEffect18, useMemo as useMemo17, useState as useState24 } from "react";
9351
8805
  import {
9352
8806
  createArrayPropUtils as createArrayPropUtils3,
9353
8807
  selectionSizePropTypeUtil as selectionSizePropTypeUtil2
@@ -9894,7 +9348,7 @@ var TransitionRepeaterControl = createControl(
9894
9348
  currentStyleState
9895
9349
  }) => {
9896
9350
  const currentStyleIsNormal = currentStyleState === null;
9897
- const [recentlyUsedList, setRecentlyUsedList] = useState23([]);
9351
+ const [recentlyUsedList, setRecentlyUsedList] = useState24([]);
9898
9352
  const proInstalled = hasProInstalled2();
9899
9353
  const { value, setValue } = useBoundProp(childArrayPropTypeUtil);
9900
9354
  const { allDisabled: disabledItems, proDisabled: proDisabledItems } = useMemo17(
@@ -10210,7 +9664,7 @@ var BoundTimeStringControl = ({ bind, ariaLabel }) => {
10210
9664
 
10211
9665
  // src/controls/inline-editing-control.tsx
10212
9666
  import * as React128 from "react";
10213
- import { useCallback as useCallback4, useState as useState25 } from "react";
9667
+ import { useCallback as useCallback4, useState as useState26 } from "react";
10214
9668
  import { escapedHtmlPropTypeUtil as escapedHtmlPropTypeUtil2 } from "@elementor/editor-props";
10215
9669
  import { Box as Box35, Stack as Stack24 } from "@elementor/ui";
10216
9670
 
@@ -10390,7 +9844,7 @@ var useOnUpdate = (callback, dependencies) => {
10390
9844
 
10391
9845
  // src/components/inline-editor-toolbar.tsx
10392
9846
  import * as React127 from "react";
10393
- import { useEffect as useEffect21, useMemo as useMemo18, useRef as useRef34, useState as useState24 } from "react";
9847
+ import { useEffect as useEffect21, useMemo as useMemo18, useRef as useRef34, useState as useState25 } from "react";
10394
9848
  import { getContainer as getContainer2, getElementSetting } from "@elementor/editor-elements";
10395
9849
  import {
10396
9850
  BoldIcon,
@@ -10485,8 +9939,8 @@ var InlineEditorToolbar = ({
10485
9939
  sx = {},
10486
9940
  inControlPanel = false
10487
9941
  }) => {
10488
- const [urlValue, setUrlValue] = useState24("");
10489
- const [openInNewTab, setOpenInNewTab] = useState24(false);
9942
+ const [urlValue, setUrlValue] = useState25("");
9943
+ const [openInNewTab, setOpenInNewTab] = useState25(false);
10490
9944
  const toolbarRef = useRef34(null);
10491
9945
  const linkPopupState = usePopupState12({ variant: "popover" });
10492
9946
  const isElementClickable = elementId ? checkIfElementIsClickable(elementId) : false;
@@ -10713,7 +10167,7 @@ var InlineEditingControl = createControl(
10713
10167
  const { setValue, placeholder, value } = useBoundProp(escapedHtmlPropTypeUtil2);
10714
10168
  const { value: rawValue } = usePropKeyContext();
10715
10169
  const content = value ?? extractInlineHtmlContent(rawValue);
10716
- const [editor, setEditor] = useState25(null);
10170
+ const [editor, setEditor] = useState26(null);
10717
10171
  const handleChange = useCallback4(
10718
10172
  (newValue) => {
10719
10173
  const html = newValue ?? "";
@@ -10901,7 +10355,7 @@ function useFormFieldSuggestions(options) {
10901
10355
 
10902
10356
  // src/controls/email-form-action-control/email-chips-field.tsx
10903
10357
  import * as React129 from "react";
10904
- import { useMemo as useMemo19, useState as useState26 } from "react";
10358
+ import { useMemo as useMemo19, useState as useState27 } from "react";
10905
10359
  import { stringArrayPropTypeUtil as stringArrayPropTypeUtil3, stringPropTypeUtil as stringPropTypeUtil23 } from "@elementor/editor-props";
10906
10360
  import { Autocomplete as Autocomplete4, Grid as Grid32, TextField as TextField12 } from "@elementor/ui";
10907
10361
 
@@ -10939,7 +10393,7 @@ function resolveMention(raw, suggestions) {
10939
10393
  }
10940
10394
  var EmailChipsControl = createControl(({ placeholder, suggestions = [] }) => {
10941
10395
  const { value, setValue, disabled } = useBoundProp(stringArrayPropTypeUtil3);
10942
- const [inputValue, setInputValue] = useState26("");
10396
+ const [inputValue, setInputValue] = useState27("");
10943
10397
  const items2 = value || [];
10944
10398
  const selectedValues = items2.map((item) => stringPropTypeUtil23.extract(item)).filter((val) => val !== null);
10945
10399
  const suggestionOptions = useMemo19(
@@ -11177,7 +10631,7 @@ import { __ as __70 } from "@wordpress/i18n";
11177
10631
 
11178
10632
  // src/components/promotions/promotion-trigger.tsx
11179
10633
  import * as React135 from "react";
11180
- import { forwardRef as forwardRef13, useCallback as useCallback5, useImperativeHandle, useState as useState27 } from "react";
10634
+ import { forwardRef as forwardRef13, useCallback as useCallback5, useImperativeHandle, useState as useState28 } from "react";
11181
10635
  import { PromotionChip as PromotionChip2, PromotionInfotip } from "@elementor/editor-ui";
11182
10636
  import { Box as Box37 } from "@elementor/ui";
11183
10637
  function getV4Promotion(key) {
@@ -11185,7 +10639,7 @@ function getV4Promotion(key) {
11185
10639
  }
11186
10640
  var PromotionTrigger = forwardRef13(
11187
10641
  ({ promotionKey, children, trackingData }, ref) => {
11188
- const [isOpen, setIsOpen] = useState27(false);
10642
+ const [isOpen, setIsOpen] = useState28(false);
11189
10643
  const promotion = getV4Promotion(promotionKey);
11190
10644
  const toggle = useCallback5(() => {
11191
10645
  setIsOpen((prev) => {
@@ -11305,7 +10759,7 @@ var ClearIconButton = ({ tooltipText, onClick, disabled, size = "tiny" }) => /*
11305
10759
 
11306
10760
  // src/components/repeater/repeater.tsx
11307
10761
  import * as React139 from "react";
11308
- import { useEffect as useEffect22, useState as useState28 } from "react";
10762
+ import { useEffect as useEffect22, useState as useState29 } from "react";
11309
10763
  import { CopyIcon as CopyIcon2, EyeIcon as EyeIcon2, EyeOffIcon as EyeOffIcon2, PlusIcon as PlusIcon5, XIcon as XIcon4 } from "@elementor/icons";
11310
10764
  import {
11311
10765
  bindPopover as bindPopover9,
@@ -11335,7 +10789,7 @@ var Repeater3 = ({
11335
10789
  isSortable = true,
11336
10790
  adornment = ControlAdornments
11337
10791
  }) => {
11338
- const [openItem, setOpenItem] = useState28(initialOpenItem);
10792
+ const [openItem, setOpenItem] = useState29(initialOpenItem);
11339
10793
  const uniqueKeys = items2.map(
11340
10794
  (item, index) => isSortable && "getId" in itemSettings ? itemSettings.getId({ item, index }) : String(index)
11341
10795
  );
@@ -11511,7 +10965,7 @@ var RepeaterItem = ({
11511
10965
  ), /* @__PURE__ */ React139.createElement(RepeaterPopover, { width: ref?.getBoundingClientRect().width, ...popoverProps, anchorEl: ref }, /* @__PURE__ */ React139.createElement(Box38, null, children({ anchorEl: ref }))));
11512
10966
  };
11513
10967
  var usePopover = (openOnMount, onOpen, onPopoverClose) => {
11514
- const [ref, setRef] = useState28(null);
10968
+ const [ref, setRef] = useState29(null);
11515
10969
  const popoverState = usePopupState13({ variant: "popover" });
11516
10970
  const popoverProps = bindPopover9(popoverState);
11517
10971
  useEffect22(() => {
@@ -11797,21 +11251,23 @@ export {
11797
11251
  createControl,
11798
11252
  createControlReplacementsRegistry,
11799
11253
  enqueueFont,
11254
+ enqueueIconFonts,
11800
11255
  getControlReplacements,
11801
11256
  getFontAwesome7IconName,
11802
11257
  injectIntoRepeaterItemActions,
11803
11258
  injectIntoRepeaterItemIcon,
11804
11259
  injectIntoRepeaterItemLabel,
11805
- isDeletedCustomIconLibrary,
11806
11260
  isUnitExtendedOption,
11807
11261
  registerControlReplacement,
11262
+ registerIconLibraryProvider,
11808
11263
  resetFontAwesome7IconsCache,
11809
- resolveCustomIconSvg,
11810
11264
  resolveFontAwesome7Icon,
11265
+ resolveProviderIconSvg,
11811
11266
  trackUpgradePromotionClick,
11812
11267
  trackViewPromotion,
11813
11268
  transitionProperties,
11814
11269
  transitionsItemsList,
11270
+ unregisterIconLibraryProvider,
11815
11271
  useBoundProp,
11816
11272
  useControlActions,
11817
11273
  useControlReplacement,