@elementor/menus 0.1.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.
- package/CHANGELOG.md +7 -0
- package/README.md +5 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +84 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
- package/src/create-menu.ts +59 -0
- package/src/create-register-item.tsx +52 -0
- package/src/create-use-menu-items.ts +33 -0
- package/src/index.ts +2 -0
- package/src/types.ts +9 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Menus
|
|
2
|
+
|
|
3
|
+
> [!WARNING]
|
|
4
|
+
> Please refrain from accessing or depending on functions and variables starting with double underscores, as they are subject to change without notice.
|
|
5
|
+
> Naming convention involving double underscores (`__`) as a prefix to indicate that a function or variable is meant for internal use and should not be accessed or relied upon by third-party developers.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ComponentType, ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
|
|
3
|
+
type Components = Record<string, ComponentType<any>>;
|
|
4
|
+
type MenuGroups<TGroups extends string> = TGroups | 'default';
|
|
5
|
+
|
|
6
|
+
type UseMenuItems<TGroups extends string> = () => GroupedMenuItems<TGroups>;
|
|
7
|
+
type GroupedMenuItems<TGroups extends string> = Record<MenuGroups<TGroups>, Array<{
|
|
8
|
+
id: string;
|
|
9
|
+
MenuItem: ComponentType;
|
|
10
|
+
}>>;
|
|
11
|
+
|
|
12
|
+
type RegisterItem<TGroups extends string, TComponent extends ComponentType> = (args: {
|
|
13
|
+
id: string;
|
|
14
|
+
group?: MenuGroups<TGroups>;
|
|
15
|
+
priority?: number;
|
|
16
|
+
overwrite?: boolean;
|
|
17
|
+
} & Props<ComponentPropsWithoutRef<TComponent>>) => void;
|
|
18
|
+
type Props<TProps extends object> = unknown extends TProps ? NoProps : PropsOrUseProps<TProps>;
|
|
19
|
+
type NoProps = {
|
|
20
|
+
props?: never;
|
|
21
|
+
useProps?: never;
|
|
22
|
+
};
|
|
23
|
+
type PropsOrUseProps<TProps extends object> = {
|
|
24
|
+
props: TProps;
|
|
25
|
+
useProps?: never;
|
|
26
|
+
} | {
|
|
27
|
+
useProps: () => TProps;
|
|
28
|
+
props?: never;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type Menu<TComponents extends Components, TGroups extends string> = {
|
|
32
|
+
useMenuItems: UseMenuItems<TGroups>;
|
|
33
|
+
} & RegisterFns<TGroups, TComponents>;
|
|
34
|
+
declare function createMenu<TComponents extends Components, TGroups extends string = 'default'>({ groups, components, }: {
|
|
35
|
+
groups?: TGroups[];
|
|
36
|
+
components: TComponents;
|
|
37
|
+
}): Menu<TComponents, TGroups>;
|
|
38
|
+
type RegisterFns<TGroups extends string, TComponents extends Components> = {
|
|
39
|
+
[K in keyof TComponents as `register${Capitalize<K & string>}`]: RegisterItem<TGroups, TComponents[K]>;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { type Components, type Menu, createMenu };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ComponentType, ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
|
|
3
|
+
type Components = Record<string, ComponentType<any>>;
|
|
4
|
+
type MenuGroups<TGroups extends string> = TGroups | 'default';
|
|
5
|
+
|
|
6
|
+
type UseMenuItems<TGroups extends string> = () => GroupedMenuItems<TGroups>;
|
|
7
|
+
type GroupedMenuItems<TGroups extends string> = Record<MenuGroups<TGroups>, Array<{
|
|
8
|
+
id: string;
|
|
9
|
+
MenuItem: ComponentType;
|
|
10
|
+
}>>;
|
|
11
|
+
|
|
12
|
+
type RegisterItem<TGroups extends string, TComponent extends ComponentType> = (args: {
|
|
13
|
+
id: string;
|
|
14
|
+
group?: MenuGroups<TGroups>;
|
|
15
|
+
priority?: number;
|
|
16
|
+
overwrite?: boolean;
|
|
17
|
+
} & Props<ComponentPropsWithoutRef<TComponent>>) => void;
|
|
18
|
+
type Props<TProps extends object> = unknown extends TProps ? NoProps : PropsOrUseProps<TProps>;
|
|
19
|
+
type NoProps = {
|
|
20
|
+
props?: never;
|
|
21
|
+
useProps?: never;
|
|
22
|
+
};
|
|
23
|
+
type PropsOrUseProps<TProps extends object> = {
|
|
24
|
+
props: TProps;
|
|
25
|
+
useProps?: never;
|
|
26
|
+
} | {
|
|
27
|
+
useProps: () => TProps;
|
|
28
|
+
props?: never;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type Menu<TComponents extends Components, TGroups extends string> = {
|
|
32
|
+
useMenuItems: UseMenuItems<TGroups>;
|
|
33
|
+
} & RegisterFns<TGroups, TComponents>;
|
|
34
|
+
declare function createMenu<TComponents extends Components, TGroups extends string = 'default'>({ groups, components, }: {
|
|
35
|
+
groups?: TGroups[];
|
|
36
|
+
components: TComponents;
|
|
37
|
+
}): Menu<TComponents, TGroups>;
|
|
38
|
+
type RegisterFns<TGroups extends string, TComponents extends Components> = {
|
|
39
|
+
[K in keyof TComponents as `register${Capitalize<K & string>}`]: RegisterItem<TGroups, TComponents[K]>;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { type Components, type Menu, createMenu };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
createMenu: () => createMenu
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(src_exports);
|
|
36
|
+
|
|
37
|
+
// src/create-menu.ts
|
|
38
|
+
var import_locations = require("@elementor/locations");
|
|
39
|
+
|
|
40
|
+
// src/create-use-menu-items.ts
|
|
41
|
+
var import_react = require("react");
|
|
42
|
+
function createUseMenuItems(locations) {
|
|
43
|
+
return () => {
|
|
44
|
+
return (0, import_react.useMemo)(() => {
|
|
45
|
+
return Object.entries(locations).reduce((carry, [groupName, location]) => {
|
|
46
|
+
const items = location.getInjections().map((injection) => ({
|
|
47
|
+
id: injection.id,
|
|
48
|
+
MenuItem: injection.component
|
|
49
|
+
}));
|
|
50
|
+
return {
|
|
51
|
+
...carry,
|
|
52
|
+
[groupName]: items
|
|
53
|
+
};
|
|
54
|
+
}, {});
|
|
55
|
+
}, []);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/create-register-item.tsx
|
|
60
|
+
var React = __toESM(require("react"));
|
|
61
|
+
function createRegisterItem(locations, component) {
|
|
62
|
+
return ({ id, group = "default", priority = 10, overwrite = false, props: _props, useProps: _useProps }) => {
|
|
63
|
+
if (!(group in locations)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const Component = component;
|
|
67
|
+
const useProps = _useProps || (() => _props);
|
|
68
|
+
const InjectedComponent = () => {
|
|
69
|
+
const props = useProps();
|
|
70
|
+
return /* @__PURE__ */ React.createElement(Component, { ...props });
|
|
71
|
+
};
|
|
72
|
+
locations[group].inject({
|
|
73
|
+
id,
|
|
74
|
+
component: InjectedComponent,
|
|
75
|
+
options: {
|
|
76
|
+
priority,
|
|
77
|
+
overwrite
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/create-menu.ts
|
|
84
|
+
function createMenu({
|
|
85
|
+
groups = [],
|
|
86
|
+
components
|
|
87
|
+
}) {
|
|
88
|
+
const locations = createLocations([...groups, "default"]);
|
|
89
|
+
const registerFns = createRegisterFns(locations, components);
|
|
90
|
+
const useMenuItems = createUseMenuItems(locations);
|
|
91
|
+
return {
|
|
92
|
+
useMenuItems,
|
|
93
|
+
...registerFns
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function createLocations(groups) {
|
|
97
|
+
return groups.reduce((acc, group) => {
|
|
98
|
+
acc[group] = (0, import_locations.createLocation)();
|
|
99
|
+
return acc;
|
|
100
|
+
}, {});
|
|
101
|
+
}
|
|
102
|
+
function createRegisterFns(locations, components) {
|
|
103
|
+
return Object.entries(components).reduce(
|
|
104
|
+
(acc, [key, component]) => {
|
|
105
|
+
const name = `register${capitalize(key)}`;
|
|
106
|
+
return {
|
|
107
|
+
...acc,
|
|
108
|
+
[name]: createRegisterItem(locations, component)
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
{}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
function capitalize(str) {
|
|
115
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
116
|
+
}
|
|
117
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
118
|
+
0 && (module.exports = {
|
|
119
|
+
createMenu
|
|
120
|
+
});
|
|
121
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/create-menu.ts","../src/create-use-menu-items.ts","../src/create-register-item.tsx"],"sourcesContent":["export { createMenu, type Menu } from './create-menu';\nexport { type Components } from './types';\n","import { createLocation } from '@elementor/locations';\nimport { Components, LocationsMap, MenuGroups } from './types';\nimport { createUseMenuItems, UseMenuItems } from './create-use-menu-items';\nimport { createRegisterItem, RegisterItem } from './create-register-item';\n\nexport type Menu< TComponents extends Components, TGroups extends string > = {\n\tuseMenuItems: UseMenuItems< TGroups >;\n} & RegisterFns< TGroups, TComponents >;\n\nexport function createMenu< TComponents extends Components, TGroups extends string = 'default' >( {\n\tgroups = [],\n\tcomponents,\n}: {\n\tgroups?: TGroups[];\n\tcomponents: TComponents;\n} ): Menu< TComponents, TGroups > {\n\tconst locations = createLocations< MenuGroups< TGroups > >( [ ...groups, 'default' ] );\n\n\tconst registerFns = createRegisterFns( locations, components );\n\tconst useMenuItems = createUseMenuItems( locations );\n\n\treturn {\n\t\tuseMenuItems,\n\t\t...registerFns,\n\t};\n}\n\nfunction createLocations< TGroups extends string >( groups: TGroups[] ) {\n\treturn groups.reduce( ( acc, group ) => {\n\t\tacc[ group ] = createLocation();\n\n\t\treturn acc;\n\t}, {} as LocationsMap< TGroups > );\n}\n\ntype RegisterFns< TGroups extends string, TComponents extends Components > = {\n\t[ K in keyof TComponents as `register${ Capitalize< K & string > }` ]: RegisterItem< TGroups, TComponents[ K ] >;\n};\n\nfunction createRegisterFns< TGroups extends string, TComponents extends Components >(\n\tlocations: LocationsMap< MenuGroups< TGroups > >,\n\tcomponents: TComponents\n) {\n\treturn Object.entries( components ).reduce(\n\t\t( acc, [ key, component ] ) => {\n\t\t\tconst name = `register${ capitalize( key ) }`;\n\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t[ name ]: createRegisterItem( locations, component ),\n\t\t\t};\n\t\t},\n\t\t{} as RegisterFns< TGroups, TComponents >\n\t);\n}\n\nfunction capitalize( str: string ) {\n\treturn str.charAt( 0 ).toUpperCase() + str.slice( 1 );\n}\n","import { ComponentType, useMemo } from 'react';\nimport { LocationsMap, MenuGroups } from './types';\n\nexport type UseMenuItems< TGroups extends string > = () => GroupedMenuItems< TGroups >;\n\ntype GroupedMenuItems< TGroups extends string > = Record<\n\tMenuGroups< TGroups >,\n\tArray< {\n\t\tid: string;\n\t\tMenuItem: ComponentType;\n\t} >\n>;\n\nexport function createUseMenuItems< TGroups extends string >(\n\tlocations: LocationsMap< MenuGroups< TGroups > >\n): UseMenuItems< TGroups > {\n\treturn () => {\n\t\t// Normalize the injections groups to an object with the groups as keys.\n\t\treturn useMemo( () => {\n\t\t\treturn Object.entries( locations ).reduce( ( carry, [ groupName, location ] ) => {\n\t\t\t\tconst items = location.getInjections().map( ( injection ) => ( {\n\t\t\t\t\tid: injection.id,\n\t\t\t\t\tMenuItem: injection.component,\n\t\t\t\t} ) );\n\n\t\t\t\treturn {\n\t\t\t\t\t...carry,\n\t\t\t\t\t[ groupName ]: items,\n\t\t\t\t};\n\t\t\t}, {} as GroupedMenuItems< TGroups > );\n\t\t}, [] );\n\t};\n}\n","import * as React from 'react';\nimport { ComponentPropsWithoutRef, ComponentType } from 'react';\nimport { LocationsMap, MenuGroups } from './types';\n\nexport type RegisterItem< TGroups extends string, TComponent extends ComponentType > = (\n\targs: {\n\t\tid: string;\n\t\tgroup?: MenuGroups< TGroups >;\n\t\tpriority?: number;\n\t\toverwrite?: boolean;\n\t} & Props< ComponentPropsWithoutRef< TComponent > >\n) => void;\n\ntype Props< TProps extends object > = unknown extends TProps ? NoProps : PropsOrUseProps< TProps >;\n\ntype NoProps = { props?: never; useProps?: never };\n\ntype PropsOrUseProps< TProps extends object > =\n\t| { props: TProps; useProps?: never }\n\t| {\n\t\t\tuseProps: () => TProps;\n\t\t\tprops?: never;\n\t };\n\nexport function createRegisterItem< TGroups extends string, TComponent extends ComponentType >(\n\tlocations: LocationsMap< MenuGroups< TGroups > >,\n\tcomponent: TComponent\n): RegisterItem< TGroups, TComponent > {\n\treturn ( { id, group = 'default', priority = 10, overwrite = false, props: _props, useProps: _useProps } ) => {\n\t\tif ( ! ( group in locations ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst Component = component as ComponentType;\n\t\tconst useProps = _useProps || ( () => _props );\n\n\t\tconst InjectedComponent = () => {\n\t\t\tconst props = useProps();\n\n\t\t\treturn <Component { ...props } />;\n\t\t};\n\n\t\tlocations[ group ].inject( {\n\t\t\tid,\n\t\t\tcomponent: InjectedComponent,\n\t\t\toptions: {\n\t\t\t\tpriority,\n\t\t\t\toverwrite,\n\t\t\t},\n\t\t} );\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uBAA+B;;;ACA/B,mBAAuC;AAahC,SAAS,mBACf,WAC0B;AAC1B,SAAO,MAAM;AAEZ,eAAO,sBAAS,MAAM;AACrB,aAAO,OAAO,QAAS,SAAU,EAAE,OAAQ,CAAE,OAAO,CAAE,WAAW,QAAS,MAAO;AAChF,cAAM,QAAQ,SAAS,cAAc,EAAE,IAAK,CAAE,eAAiB;AAAA,UAC9D,IAAI,UAAU;AAAA,UACd,UAAU,UAAU;AAAA,QACrB,EAAI;AAEJ,eAAO;AAAA,UACN,GAAG;AAAA,UACH,CAAE,SAAU,GAAG;AAAA,QAChB;AAAA,MACD,GAAG,CAAC,CAAiC;AAAA,IACtC,GAAG,CAAC,CAAE;AAAA,EACP;AACD;;;AChCA,YAAuB;AAwBhB,SAAS,mBACf,WACA,WACsC;AACtC,SAAO,CAAE,EAAE,IAAI,QAAQ,WAAW,WAAW,IAAI,YAAY,OAAO,OAAO,QAAQ,UAAU,UAAU,MAAO;AAC7G,QAAK,EAAI,SAAS,YAAc;AAC/B;AAAA,IACD;AAEA,UAAM,YAAY;AAClB,UAAM,WAAW,cAAe,MAAM;AAEtC,UAAM,oBAAoB,MAAM;AAC/B,YAAM,QAAQ,SAAS;AAEvB,aAAO,oCAAC,aAAY,GAAG,OAAQ;AAAA,IAChC;AAEA,cAAW,KAAM,EAAE,OAAQ;AAAA,MAC1B;AAAA,MACA,WAAW;AAAA,MACX,SAAS;AAAA,QACR;AAAA,QACA;AAAA,MACD;AAAA,IACD,CAAE;AAAA,EACH;AACD;;;AF1CO,SAAS,WAAkF;AAAA,EACjG,SAAS,CAAC;AAAA,EACV;AACD,GAGkC;AACjC,QAAM,YAAY,gBAA0C,CAAE,GAAG,QAAQ,SAAU,CAAE;AAErF,QAAM,cAAc,kBAAmB,WAAW,UAAW;AAC7D,QAAM,eAAe,mBAAoB,SAAU;AAEnD,SAAO;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EACJ;AACD;AAEA,SAAS,gBAA2C,QAAoB;AACvE,SAAO,OAAO,OAAQ,CAAE,KAAK,UAAW;AACvC,QAAK,KAAM,QAAI,iCAAe;AAE9B,WAAO;AAAA,EACR,GAAG,CAAC,CAA6B;AAClC;AAMA,SAAS,kBACR,WACA,YACC;AACD,SAAO,OAAO,QAAS,UAAW,EAAE;AAAA,IACnC,CAAE,KAAK,CAAE,KAAK,SAAU,MAAO;AAC9B,YAAM,OAAO,WAAY,WAAY,GAAI,CAAE;AAE3C,aAAO;AAAA,QACN,GAAG;AAAA,QACH,CAAE,IAAK,GAAG,mBAAoB,WAAW,SAAU;AAAA,MACpD;AAAA,IACD;AAAA,IACA,CAAC;AAAA,EACF;AACD;AAEA,SAAS,WAAY,KAAc;AAClC,SAAO,IAAI,OAAQ,CAAE,EAAE,YAAY,IAAI,IAAI,MAAO,CAAE;AACrD;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// src/create-menu.ts
|
|
2
|
+
import { createLocation } from "@elementor/locations";
|
|
3
|
+
|
|
4
|
+
// src/create-use-menu-items.ts
|
|
5
|
+
import { useMemo } from "react";
|
|
6
|
+
function createUseMenuItems(locations) {
|
|
7
|
+
return () => {
|
|
8
|
+
return useMemo(() => {
|
|
9
|
+
return Object.entries(locations).reduce((carry, [groupName, location]) => {
|
|
10
|
+
const items = location.getInjections().map((injection) => ({
|
|
11
|
+
id: injection.id,
|
|
12
|
+
MenuItem: injection.component
|
|
13
|
+
}));
|
|
14
|
+
return {
|
|
15
|
+
...carry,
|
|
16
|
+
[groupName]: items
|
|
17
|
+
};
|
|
18
|
+
}, {});
|
|
19
|
+
}, []);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/create-register-item.tsx
|
|
24
|
+
import * as React from "react";
|
|
25
|
+
function createRegisterItem(locations, component) {
|
|
26
|
+
return ({ id, group = "default", priority = 10, overwrite = false, props: _props, useProps: _useProps }) => {
|
|
27
|
+
if (!(group in locations)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const Component = component;
|
|
31
|
+
const useProps = _useProps || (() => _props);
|
|
32
|
+
const InjectedComponent = () => {
|
|
33
|
+
const props = useProps();
|
|
34
|
+
return /* @__PURE__ */ React.createElement(Component, { ...props });
|
|
35
|
+
};
|
|
36
|
+
locations[group].inject({
|
|
37
|
+
id,
|
|
38
|
+
component: InjectedComponent,
|
|
39
|
+
options: {
|
|
40
|
+
priority,
|
|
41
|
+
overwrite
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/create-menu.ts
|
|
48
|
+
function createMenu({
|
|
49
|
+
groups = [],
|
|
50
|
+
components
|
|
51
|
+
}) {
|
|
52
|
+
const locations = createLocations([...groups, "default"]);
|
|
53
|
+
const registerFns = createRegisterFns(locations, components);
|
|
54
|
+
const useMenuItems = createUseMenuItems(locations);
|
|
55
|
+
return {
|
|
56
|
+
useMenuItems,
|
|
57
|
+
...registerFns
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function createLocations(groups) {
|
|
61
|
+
return groups.reduce((acc, group) => {
|
|
62
|
+
acc[group] = createLocation();
|
|
63
|
+
return acc;
|
|
64
|
+
}, {});
|
|
65
|
+
}
|
|
66
|
+
function createRegisterFns(locations, components) {
|
|
67
|
+
return Object.entries(components).reduce(
|
|
68
|
+
(acc, [key, component]) => {
|
|
69
|
+
const name = `register${capitalize(key)}`;
|
|
70
|
+
return {
|
|
71
|
+
...acc,
|
|
72
|
+
[name]: createRegisterItem(locations, component)
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
{}
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function capitalize(str) {
|
|
79
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
createMenu
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/create-menu.ts","../src/create-use-menu-items.ts","../src/create-register-item.tsx"],"sourcesContent":["import { createLocation } from '@elementor/locations';\nimport { Components, LocationsMap, MenuGroups } from './types';\nimport { createUseMenuItems, UseMenuItems } from './create-use-menu-items';\nimport { createRegisterItem, RegisterItem } from './create-register-item';\n\nexport type Menu< TComponents extends Components, TGroups extends string > = {\n\tuseMenuItems: UseMenuItems< TGroups >;\n} & RegisterFns< TGroups, TComponents >;\n\nexport function createMenu< TComponents extends Components, TGroups extends string = 'default' >( {\n\tgroups = [],\n\tcomponents,\n}: {\n\tgroups?: TGroups[];\n\tcomponents: TComponents;\n} ): Menu< TComponents, TGroups > {\n\tconst locations = createLocations< MenuGroups< TGroups > >( [ ...groups, 'default' ] );\n\n\tconst registerFns = createRegisterFns( locations, components );\n\tconst useMenuItems = createUseMenuItems( locations );\n\n\treturn {\n\t\tuseMenuItems,\n\t\t...registerFns,\n\t};\n}\n\nfunction createLocations< TGroups extends string >( groups: TGroups[] ) {\n\treturn groups.reduce( ( acc, group ) => {\n\t\tacc[ group ] = createLocation();\n\n\t\treturn acc;\n\t}, {} as LocationsMap< TGroups > );\n}\n\ntype RegisterFns< TGroups extends string, TComponents extends Components > = {\n\t[ K in keyof TComponents as `register${ Capitalize< K & string > }` ]: RegisterItem< TGroups, TComponents[ K ] >;\n};\n\nfunction createRegisterFns< TGroups extends string, TComponents extends Components >(\n\tlocations: LocationsMap< MenuGroups< TGroups > >,\n\tcomponents: TComponents\n) {\n\treturn Object.entries( components ).reduce(\n\t\t( acc, [ key, component ] ) => {\n\t\t\tconst name = `register${ capitalize( key ) }`;\n\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t[ name ]: createRegisterItem( locations, component ),\n\t\t\t};\n\t\t},\n\t\t{} as RegisterFns< TGroups, TComponents >\n\t);\n}\n\nfunction capitalize( str: string ) {\n\treturn str.charAt( 0 ).toUpperCase() + str.slice( 1 );\n}\n","import { ComponentType, useMemo } from 'react';\nimport { LocationsMap, MenuGroups } from './types';\n\nexport type UseMenuItems< TGroups extends string > = () => GroupedMenuItems< TGroups >;\n\ntype GroupedMenuItems< TGroups extends string > = Record<\n\tMenuGroups< TGroups >,\n\tArray< {\n\t\tid: string;\n\t\tMenuItem: ComponentType;\n\t} >\n>;\n\nexport function createUseMenuItems< TGroups extends string >(\n\tlocations: LocationsMap< MenuGroups< TGroups > >\n): UseMenuItems< TGroups > {\n\treturn () => {\n\t\t// Normalize the injections groups to an object with the groups as keys.\n\t\treturn useMemo( () => {\n\t\t\treturn Object.entries( locations ).reduce( ( carry, [ groupName, location ] ) => {\n\t\t\t\tconst items = location.getInjections().map( ( injection ) => ( {\n\t\t\t\t\tid: injection.id,\n\t\t\t\t\tMenuItem: injection.component,\n\t\t\t\t} ) );\n\n\t\t\t\treturn {\n\t\t\t\t\t...carry,\n\t\t\t\t\t[ groupName ]: items,\n\t\t\t\t};\n\t\t\t}, {} as GroupedMenuItems< TGroups > );\n\t\t}, [] );\n\t};\n}\n","import * as React from 'react';\nimport { ComponentPropsWithoutRef, ComponentType } from 'react';\nimport { LocationsMap, MenuGroups } from './types';\n\nexport type RegisterItem< TGroups extends string, TComponent extends ComponentType > = (\n\targs: {\n\t\tid: string;\n\t\tgroup?: MenuGroups< TGroups >;\n\t\tpriority?: number;\n\t\toverwrite?: boolean;\n\t} & Props< ComponentPropsWithoutRef< TComponent > >\n) => void;\n\ntype Props< TProps extends object > = unknown extends TProps ? NoProps : PropsOrUseProps< TProps >;\n\ntype NoProps = { props?: never; useProps?: never };\n\ntype PropsOrUseProps< TProps extends object > =\n\t| { props: TProps; useProps?: never }\n\t| {\n\t\t\tuseProps: () => TProps;\n\t\t\tprops?: never;\n\t };\n\nexport function createRegisterItem< TGroups extends string, TComponent extends ComponentType >(\n\tlocations: LocationsMap< MenuGroups< TGroups > >,\n\tcomponent: TComponent\n): RegisterItem< TGroups, TComponent > {\n\treturn ( { id, group = 'default', priority = 10, overwrite = false, props: _props, useProps: _useProps } ) => {\n\t\tif ( ! ( group in locations ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst Component = component as ComponentType;\n\t\tconst useProps = _useProps || ( () => _props );\n\n\t\tconst InjectedComponent = () => {\n\t\t\tconst props = useProps();\n\n\t\t\treturn <Component { ...props } />;\n\t\t};\n\n\t\tlocations[ group ].inject( {\n\t\t\tid,\n\t\t\tcomponent: InjectedComponent,\n\t\t\toptions: {\n\t\t\t\tpriority,\n\t\t\t\toverwrite,\n\t\t\t},\n\t\t} );\n\t};\n}\n"],"mappings":";AAAA,SAAS,sBAAsB;;;ACA/B,SAAwB,eAAe;AAahC,SAAS,mBACf,WAC0B;AAC1B,SAAO,MAAM;AAEZ,WAAO,QAAS,MAAM;AACrB,aAAO,OAAO,QAAS,SAAU,EAAE,OAAQ,CAAE,OAAO,CAAE,WAAW,QAAS,MAAO;AAChF,cAAM,QAAQ,SAAS,cAAc,EAAE,IAAK,CAAE,eAAiB;AAAA,UAC9D,IAAI,UAAU;AAAA,UACd,UAAU,UAAU;AAAA,QACrB,EAAI;AAEJ,eAAO;AAAA,UACN,GAAG;AAAA,UACH,CAAE,SAAU,GAAG;AAAA,QAChB;AAAA,MACD,GAAG,CAAC,CAAiC;AAAA,IACtC,GAAG,CAAC,CAAE;AAAA,EACP;AACD;;;AChCA,YAAY,WAAW;AAwBhB,SAAS,mBACf,WACA,WACsC;AACtC,SAAO,CAAE,EAAE,IAAI,QAAQ,WAAW,WAAW,IAAI,YAAY,OAAO,OAAO,QAAQ,UAAU,UAAU,MAAO;AAC7G,QAAK,EAAI,SAAS,YAAc;AAC/B;AAAA,IACD;AAEA,UAAM,YAAY;AAClB,UAAM,WAAW,cAAe,MAAM;AAEtC,UAAM,oBAAoB,MAAM;AAC/B,YAAM,QAAQ,SAAS;AAEvB,aAAO,oCAAC,aAAY,GAAG,OAAQ;AAAA,IAChC;AAEA,cAAW,KAAM,EAAE,OAAQ;AAAA,MAC1B;AAAA,MACA,WAAW;AAAA,MACX,SAAS;AAAA,QACR;AAAA,QACA;AAAA,MACD;AAAA,IACD,CAAE;AAAA,EACH;AACD;;;AF1CO,SAAS,WAAkF;AAAA,EACjG,SAAS,CAAC;AAAA,EACV;AACD,GAGkC;AACjC,QAAM,YAAY,gBAA0C,CAAE,GAAG,QAAQ,SAAU,CAAE;AAErF,QAAM,cAAc,kBAAmB,WAAW,UAAW;AAC7D,QAAM,eAAe,mBAAoB,SAAU;AAEnD,SAAO;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EACJ;AACD;AAEA,SAAS,gBAA2C,QAAoB;AACvE,SAAO,OAAO,OAAQ,CAAE,KAAK,UAAW;AACvC,QAAK,KAAM,IAAI,eAAe;AAE9B,WAAO;AAAA,EACR,GAAG,CAAC,CAA6B;AAClC;AAMA,SAAS,kBACR,WACA,YACC;AACD,SAAO,OAAO,QAAS,UAAW,EAAE;AAAA,IACnC,CAAE,KAAK,CAAE,KAAK,SAAU,MAAO;AAC9B,YAAM,OAAO,WAAY,WAAY,GAAI,CAAE;AAE3C,aAAO;AAAA,QACN,GAAG;AAAA,QACH,CAAE,IAAK,GAAG,mBAAoB,WAAW,SAAU;AAAA,MACpD;AAAA,IACD;AAAA,IACA,CAAC;AAAA,EACF;AACD;AAEA,SAAS,WAAY,KAAc;AAClC,SAAO,IAAI,OAAQ,CAAE,EAAE,YAAY,IAAI,IAAI,MAAO,CAAE;AACrD;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@elementor/menus",
|
|
3
|
+
"description": "Add a menus registration mechanism for you React application",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"private": false,
|
|
6
|
+
"author": "Elementor Team",
|
|
7
|
+
"homepage": "https://elementor.com/",
|
|
8
|
+
"license": "GPL-3.0-or-later",
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"module": "dist/index.mjs",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/elementor/elementor-packages.git",
|
|
23
|
+
"directory": "packages/libs/menus"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/elementor/elementor-packages/issues"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"README.md",
|
|
33
|
+
"CHANGELOG.md",
|
|
34
|
+
"/dist",
|
|
35
|
+
"/src",
|
|
36
|
+
"!**/__tests__"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsup --config=../../tsup.build.ts",
|
|
40
|
+
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@elementor/locations": "^0.7.5"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"react": "^18.3.1"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createLocation } from '@elementor/locations';
|
|
2
|
+
import { Components, LocationsMap, MenuGroups } from './types';
|
|
3
|
+
import { createUseMenuItems, UseMenuItems } from './create-use-menu-items';
|
|
4
|
+
import { createRegisterItem, RegisterItem } from './create-register-item';
|
|
5
|
+
|
|
6
|
+
export type Menu< TComponents extends Components, TGroups extends string > = {
|
|
7
|
+
useMenuItems: UseMenuItems< TGroups >;
|
|
8
|
+
} & RegisterFns< TGroups, TComponents >;
|
|
9
|
+
|
|
10
|
+
export function createMenu< TComponents extends Components, TGroups extends string = 'default' >( {
|
|
11
|
+
groups = [],
|
|
12
|
+
components,
|
|
13
|
+
}: {
|
|
14
|
+
groups?: TGroups[];
|
|
15
|
+
components: TComponents;
|
|
16
|
+
} ): Menu< TComponents, TGroups > {
|
|
17
|
+
const locations = createLocations< MenuGroups< TGroups > >( [ ...groups, 'default' ] );
|
|
18
|
+
|
|
19
|
+
const registerFns = createRegisterFns( locations, components );
|
|
20
|
+
const useMenuItems = createUseMenuItems( locations );
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
useMenuItems,
|
|
24
|
+
...registerFns,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function createLocations< TGroups extends string >( groups: TGroups[] ) {
|
|
29
|
+
return groups.reduce( ( acc, group ) => {
|
|
30
|
+
acc[ group ] = createLocation();
|
|
31
|
+
|
|
32
|
+
return acc;
|
|
33
|
+
}, {} as LocationsMap< TGroups > );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type RegisterFns< TGroups extends string, TComponents extends Components > = {
|
|
37
|
+
[ K in keyof TComponents as `register${ Capitalize< K & string > }` ]: RegisterItem< TGroups, TComponents[ K ] >;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function createRegisterFns< TGroups extends string, TComponents extends Components >(
|
|
41
|
+
locations: LocationsMap< MenuGroups< TGroups > >,
|
|
42
|
+
components: TComponents
|
|
43
|
+
) {
|
|
44
|
+
return Object.entries( components ).reduce(
|
|
45
|
+
( acc, [ key, component ] ) => {
|
|
46
|
+
const name = `register${ capitalize( key ) }`;
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
...acc,
|
|
50
|
+
[ name ]: createRegisterItem( locations, component ),
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
{} as RegisterFns< TGroups, TComponents >
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function capitalize( str: string ) {
|
|
58
|
+
return str.charAt( 0 ).toUpperCase() + str.slice( 1 );
|
|
59
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ComponentPropsWithoutRef, ComponentType } from 'react';
|
|
3
|
+
import { LocationsMap, MenuGroups } from './types';
|
|
4
|
+
|
|
5
|
+
export type RegisterItem< TGroups extends string, TComponent extends ComponentType > = (
|
|
6
|
+
args: {
|
|
7
|
+
id: string;
|
|
8
|
+
group?: MenuGroups< TGroups >;
|
|
9
|
+
priority?: number;
|
|
10
|
+
overwrite?: boolean;
|
|
11
|
+
} & Props< ComponentPropsWithoutRef< TComponent > >
|
|
12
|
+
) => void;
|
|
13
|
+
|
|
14
|
+
type Props< TProps extends object > = unknown extends TProps ? NoProps : PropsOrUseProps< TProps >;
|
|
15
|
+
|
|
16
|
+
type NoProps = { props?: never; useProps?: never };
|
|
17
|
+
|
|
18
|
+
type PropsOrUseProps< TProps extends object > =
|
|
19
|
+
| { props: TProps; useProps?: never }
|
|
20
|
+
| {
|
|
21
|
+
useProps: () => TProps;
|
|
22
|
+
props?: never;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function createRegisterItem< TGroups extends string, TComponent extends ComponentType >(
|
|
26
|
+
locations: LocationsMap< MenuGroups< TGroups > >,
|
|
27
|
+
component: TComponent
|
|
28
|
+
): RegisterItem< TGroups, TComponent > {
|
|
29
|
+
return ( { id, group = 'default', priority = 10, overwrite = false, props: _props, useProps: _useProps } ) => {
|
|
30
|
+
if ( ! ( group in locations ) ) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const Component = component as ComponentType;
|
|
35
|
+
const useProps = _useProps || ( () => _props );
|
|
36
|
+
|
|
37
|
+
const InjectedComponent = () => {
|
|
38
|
+
const props = useProps();
|
|
39
|
+
|
|
40
|
+
return <Component { ...props } />;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
locations[ group ].inject( {
|
|
44
|
+
id,
|
|
45
|
+
component: InjectedComponent,
|
|
46
|
+
options: {
|
|
47
|
+
priority,
|
|
48
|
+
overwrite,
|
|
49
|
+
},
|
|
50
|
+
} );
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ComponentType, useMemo } from 'react';
|
|
2
|
+
import { LocationsMap, MenuGroups } from './types';
|
|
3
|
+
|
|
4
|
+
export type UseMenuItems< TGroups extends string > = () => GroupedMenuItems< TGroups >;
|
|
5
|
+
|
|
6
|
+
type GroupedMenuItems< TGroups extends string > = Record<
|
|
7
|
+
MenuGroups< TGroups >,
|
|
8
|
+
Array< {
|
|
9
|
+
id: string;
|
|
10
|
+
MenuItem: ComponentType;
|
|
11
|
+
} >
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function createUseMenuItems< TGroups extends string >(
|
|
15
|
+
locations: LocationsMap< MenuGroups< TGroups > >
|
|
16
|
+
): UseMenuItems< TGroups > {
|
|
17
|
+
return () => {
|
|
18
|
+
// Normalize the injections groups to an object with the groups as keys.
|
|
19
|
+
return useMemo( () => {
|
|
20
|
+
return Object.entries( locations ).reduce( ( carry, [ groupName, location ] ) => {
|
|
21
|
+
const items = location.getInjections().map( ( injection ) => ( {
|
|
22
|
+
id: injection.id,
|
|
23
|
+
MenuItem: injection.component,
|
|
24
|
+
} ) );
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
...carry,
|
|
28
|
+
[ groupName ]: items,
|
|
29
|
+
};
|
|
30
|
+
}, {} as GroupedMenuItems< TGroups > );
|
|
31
|
+
}, [] );
|
|
32
|
+
};
|
|
33
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Location } from '@elementor/locations';
|
|
2
|
+
import { ComponentType } from 'react';
|
|
3
|
+
|
|
4
|
+
export type LocationsMap< TGroups extends string > = Record< TGroups, Location >;
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Required for TS to infer the props properly.
|
|
7
|
+
export type Components = Record< string, ComponentType< any > >;
|
|
8
|
+
|
|
9
|
+
export type MenuGroups< TGroups extends string > = TGroups | 'default';
|