@rnaga/wp-next-ui 1.0.1

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.
Files changed (190) hide show
  1. package/Accordion.d.ts +4 -0
  2. package/Accordion.d.ts.map +1 -0
  3. package/Accordion.js +13 -0
  4. package/Accordions.d.ts +19 -0
  5. package/Accordions.d.ts.map +1 -0
  6. package/Accordions.js +39 -0
  7. package/Background.d.ts +5 -0
  8. package/Background.d.ts.map +1 -0
  9. package/Background.js +18 -0
  10. package/BadgeOnMouseOver.d.ts +12 -0
  11. package/BadgeOnMouseOver.d.ts.map +1 -0
  12. package/BadgeOnMouseOver.js +40 -0
  13. package/BasicMenuButton.d.ts +17 -0
  14. package/BasicMenuButton.d.ts.map +1 -0
  15. package/BasicMenuButton.js +61 -0
  16. package/Button.d.ts +10 -0
  17. package/Button.d.ts.map +1 -0
  18. package/Button.js +15 -0
  19. package/Card.d.ts +6 -0
  20. package/Card.d.ts.map +1 -0
  21. package/Card.js +13 -0
  22. package/CardImage.d.ts +10 -0
  23. package/CardImage.d.ts.map +1 -0
  24. package/CardImage.js +34 -0
  25. package/Checkbox.d.ts +6 -0
  26. package/Checkbox.d.ts.map +1 -0
  27. package/Checkbox.js +13 -0
  28. package/Chip.d.ts +10 -0
  29. package/Chip.d.ts.map +1 -0
  30. package/Chip.js +41 -0
  31. package/DateTimePicker.d.ts +6 -0
  32. package/DateTimePicker.d.ts.map +1 -0
  33. package/DateTimePicker.js +45 -0
  34. package/DraggableBox.d.ts +39 -0
  35. package/DraggableBox.d.ts.map +1 -0
  36. package/DraggableBox.js +171 -0
  37. package/Form.d.ts +4 -0
  38. package/Form.d.ts.map +1 -0
  39. package/Form.js +8 -0
  40. package/FormDataProvider.d.ts +5 -0
  41. package/FormDataProvider.d.ts.map +1 -0
  42. package/FormDataProvider.js +6 -0
  43. package/IconButtonDelete.d.ts +6 -0
  44. package/IconButtonDelete.d.ts.map +1 -0
  45. package/IconButtonDelete.js +14 -0
  46. package/Input.d.ts +14 -0
  47. package/Input.d.ts.map +1 -0
  48. package/Input.js +84 -0
  49. package/InputClickField.d.ts +13 -0
  50. package/InputClickField.d.ts.map +1 -0
  51. package/InputClickField.js +21 -0
  52. package/InputColor.d.ts +12 -0
  53. package/InputColor.d.ts.map +1 -0
  54. package/InputColor.js +141 -0
  55. package/InputMultiple.d.ts +15 -0
  56. package/InputMultiple.d.ts.map +1 -0
  57. package/InputMultiple.js +55 -0
  58. package/InputSearch.d.ts +7 -0
  59. package/InputSearch.d.ts.map +1 -0
  60. package/InputSearch.js +28 -0
  61. package/Link.d.ts +6 -0
  62. package/Link.d.ts.map +1 -0
  63. package/Link.js +15 -0
  64. package/LinkCopy.d.ts +6 -0
  65. package/LinkCopy.d.ts.map +1 -0
  66. package/LinkCopy.js +17 -0
  67. package/Loading.d.ts +7 -0
  68. package/Loading.d.ts.map +1 -0
  69. package/Loading.js +29 -0
  70. package/LoadingBox.d.ts +12 -0
  71. package/LoadingBox.d.ts.map +1 -0
  72. package/LoadingBox.js +30 -0
  73. package/MediaTag.d.ts +9 -0
  74. package/MediaTag.d.ts.map +1 -0
  75. package/MediaTag.js +19 -0
  76. package/Modal.d.ts +11 -0
  77. package/Modal.d.ts.map +1 -0
  78. package/Modal.js +65 -0
  79. package/ModalConfirm.d.ts +8 -0
  80. package/ModalConfirm.d.ts.map +1 -0
  81. package/ModalConfirm.js +58 -0
  82. package/PopperMenu.d.ts +7 -0
  83. package/PopperMenu.d.ts.map +1 -0
  84. package/PopperMenu.js +6 -0
  85. package/README.md +292 -0
  86. package/Select.d.ts +21 -0
  87. package/Select.d.ts.map +1 -0
  88. package/Select.js +23 -0
  89. package/SelectAutocomplete.d.ts +1208 -0
  90. package/SelectAutocomplete.d.ts.map +1 -0
  91. package/SelectAutocomplete.js +113 -0
  92. package/SelectMultiple.d.ts +16 -0
  93. package/SelectMultiple.d.ts.map +1 -0
  94. package/SelectMultiple.js +28 -0
  95. package/SelectWPPost.d.ts +17 -0
  96. package/SelectWPPost.d.ts.map +1 -0
  97. package/SelectWPPost.js +98 -0
  98. package/SelectWPTaxonomy.d.ts +9 -0
  99. package/SelectWPTaxonomy.d.ts.map +1 -0
  100. package/SelectWPTaxonomy.js +35 -0
  101. package/SelectWPTerm.d.ts +13 -0
  102. package/SelectWPTerm.d.ts.map +1 -0
  103. package/SelectWPTerm.js +92 -0
  104. package/SelectWPTerms.d.ts +27 -0
  105. package/SelectWPTerms.d.ts.map +1 -0
  106. package/SelectWPTerms.js +105 -0
  107. package/SelectWPUser.d.ts +16 -0
  108. package/SelectWPUser.d.ts.map +1 -0
  109. package/SelectWPUser.js +101 -0
  110. package/SortableList.d.ts +28 -0
  111. package/SortableList.d.ts.map +1 -0
  112. package/SortableList.js +195 -0
  113. package/Tabs.d.ts +17 -0
  114. package/Tabs.d.ts.map +1 -0
  115. package/Tabs.js +35 -0
  116. package/ThemeRegistry.d.ts +13 -0
  117. package/ThemeRegistry.d.ts.map +1 -0
  118. package/ThemeRegistry.js +36 -0
  119. package/Typography.d.ts +9 -0
  120. package/Typography.d.ts.map +1 -0
  121. package/Typography.js +12 -0
  122. package/Viewport.d.ts +6 -0
  123. package/Viewport.d.ts.map +1 -0
  124. package/Viewport.js +10 -0
  125. package/hooks/use-form-data.d.ts +39 -0
  126. package/hooks/use-form-data.d.ts.map +1 -0
  127. package/hooks/use-form-data.js +91 -0
  128. package/hooks/use-media-selector.d.ts +10 -0
  129. package/hooks/use-media-selector.d.ts.map +1 -0
  130. package/hooks/use-media-selector.js +33 -0
  131. package/hooks/use-mouse-move.d.ts +18 -0
  132. package/hooks/use-mouse-move.d.ts.map +1 -0
  133. package/hooks/use-mouse-move.js +112 -0
  134. package/hooks/use-scheme-toggle.d.ts +6 -0
  135. package/hooks/use-scheme-toggle.d.ts.map +1 -0
  136. package/hooks/use-scheme-toggle.js +16 -0
  137. package/hooks/use-viewport.d.ts +5 -0
  138. package/hooks/use-viewport.d.ts.map +1 -0
  139. package/hooks/use-viewport.js +9 -0
  140. package/list/ListGrid.d.ts +12 -0
  141. package/list/ListGrid.d.ts.map +1 -0
  142. package/list/ListGrid.js +15 -0
  143. package/list/ListTable.d.ts +43 -0
  144. package/list/ListTable.d.ts.map +1 -0
  145. package/list/ListTable.js +143 -0
  146. package/list/Pagination.d.ts +5 -0
  147. package/list/Pagination.d.ts.map +1 -0
  148. package/list/Pagination.js +24 -0
  149. package/list/index.d.ts +4 -0
  150. package/list/index.d.ts.map +1 -0
  151. package/list/index.js +3 -0
  152. package/media/MediaGridForm.d.ts +5 -0
  153. package/media/MediaGridForm.d.ts.map +1 -0
  154. package/media/MediaGridForm.js +128 -0
  155. package/media/MediaThumbnail.d.ts +4 -0
  156. package/media/MediaThumbnail.d.ts.map +1 -0
  157. package/media/MediaThumbnail.js +17 -0
  158. package/media/MediaUpload.d.ts +7 -0
  159. package/media/MediaUpload.d.ts.map +1 -0
  160. package/media/MediaUpload.js +76 -0
  161. package/media/index.d.ts +4 -0
  162. package/media/index.d.ts.map +1 -0
  163. package/media/index.js +3 -0
  164. package/media-selector/MediaSelectorList.d.ts +2 -0
  165. package/media-selector/MediaSelectorList.d.ts.map +1 -0
  166. package/media-selector/MediaSelectorList.js +43 -0
  167. package/media-selector/MediaSelectorPreview.d.ts +2 -0
  168. package/media-selector/MediaSelectorPreview.d.ts.map +1 -0
  169. package/media-selector/MediaSelectorPreview.js +80 -0
  170. package/media-selector/index.d.ts +2 -0
  171. package/media-selector/index.d.ts.map +1 -0
  172. package/media-selector/index.js +49 -0
  173. package/package.json +33 -0
  174. package/portal/Portal.d.ts +6 -0
  175. package/portal/Portal.d.ts.map +1 -0
  176. package/portal/Portal.js +7 -0
  177. package/portal/index.d.ts +3 -0
  178. package/portal/index.d.ts.map +1 -0
  179. package/portal/index.js +2 -0
  180. package/portal/use-portal.d.ts +4 -0
  181. package/portal/use-portal.d.ts.map +1 -0
  182. package/portal/use-portal.js +11 -0
  183. package/types/global-state.d.ts +27 -0
  184. package/types/hooks/filters.d.ts +20 -0
  185. package/types/hooks/index.d.ts +1 -0
  186. package/types/index.d.ts +3 -0
  187. package/types/wp-theme.d.ts +49 -0
  188. package/wp-theme/index.d.ts +3 -0
  189. package/wp-theme/index.d.ts.map +1 -0
  190. package/wp-theme/index.js +86 -0
package/Link.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Link as MuiLink } from "@mui/material";
2
+ import { ReactNode } from "react";
3
+ export declare const Link: (props: Parameters<typeof MuiLink>[0] & {
4
+ children: ReactNode;
5
+ } & Record<string, any>) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=Link.d.ts.map
package/Link.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../src/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,eAAO,MAAM,IAAI,GACf,OAAO,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,MAAM,CACnE,MAAM,EACN,GAAG,CACJ,4CAwBJ,CAAC"}
package/Link.js ADDED
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Link as MuiLink } from "@mui/material";
3
+ export const Link = (props) => {
4
+ const { children, sx, component, ...rest } = props;
5
+ return (_jsx(MuiLink, { ...rest, underline: "none", component: component || "a", sx: {
6
+ display: "inline",
7
+ p: 0,
8
+ m: 0,
9
+ cursor: "pointer",
10
+ "&:hover": {
11
+ backgroundColor: (theme) => theme.palette.action.hover,
12
+ },
13
+ ...sx,
14
+ }, children: children }));
15
+ };
package/LinkCopy.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare const LinkCopy: (props: {
2
+ link: string;
3
+ showIcon: boolean;
4
+ size?: "small" | "medium" | "large";
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=LinkCopy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkCopy.d.ts","sourceRoot":"","sources":["../src/LinkCopy.tsx"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ,GAAI,OAAO;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrC,4CA4BA,CAAC"}
package/LinkCopy.js ADDED
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Link } from "./Link";
4
+ import CheckIcon from "@mui/icons-material/Check";
5
+ import ContentCopyIcon from "@mui/icons-material/ContentCopy";
6
+ import { Typography } from "./Typography";
7
+ export const LinkCopy = (props) => {
8
+ const { link, showIcon = true, size = "small" } = props;
9
+ const [copied, setCopied] = useState(false);
10
+ return copied ? (showIcon ? (_jsx(CheckIcon, { fontSize: size })) : (_jsx(Typography, { size: size, color: "success", children: "Copied" }))) : (_jsx(_Fragment, { children: _jsx(Link, { fontSize: size, onClick: () => {
11
+ navigator.clipboard.writeText(link);
12
+ setCopied(true);
13
+ setTimeout(() => {
14
+ setCopied(false);
15
+ }, 1000);
16
+ }, children: showIcon ? _jsx(ContentCopyIcon, {}) : "Copy URL" }) }));
17
+ };
package/Loading.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { SxProps } from "@mui/material";
2
+ export declare const Loading: (props: {
3
+ children?: React.ReactNode;
4
+ loading: boolean;
5
+ sx?: SxProps;
6
+ }) => string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode>> | import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=Loading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Loading.d.ts","sourceRoot":"","sources":["../src/Loading.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7D,eAAO,MAAM,OAAO,GAAI,OAAO;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,OAAO,CAAC;CACd,sUA+CA,CAAC"}
package/Loading.js ADDED
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, LinearProgress } from "@mui/material";
3
+ export const Loading = (props) => {
4
+ const { children, loading } = props;
5
+ if (!loading) {
6
+ return children;
7
+ }
8
+ return (_jsx(Box, { sx: {
9
+ ...props.sx,
10
+ width: "inherit",
11
+ height: "inherit",
12
+ position: "relative",
13
+ }, children: _jsxs(_Fragment, { children: [_jsx(Box, { sx: {
14
+ position: "absolute",
15
+ zIndex: 100,
16
+ top: 0,
17
+ width: "100%",
18
+ }, children: _jsx(Box, { sx: {
19
+ width: "100%",
20
+ }, children: _jsx(LinearProgress, {}) }) }), _jsx(Box, { sx: {
21
+ position: "absolute",
22
+ zIndex: 100,
23
+ left: 0,
24
+ top: 0,
25
+ width: "100%",
26
+ height: "100%",
27
+ opacity: "30%",
28
+ } })] }) }));
29
+ };
@@ -0,0 +1,12 @@
1
+ import { SxProps } from "@mui/material";
2
+ export declare const LoadingBox: (props: {
3
+ children?: React.ReactNode;
4
+ loading: boolean;
5
+ size?: "small" | "medium";
6
+ sx?: SxProps;
7
+ slotSxProps?: {
8
+ innerBox?: SxProps;
9
+ progress?: SxProps;
10
+ };
11
+ }) => string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode>> | import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=LoadingBox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadingBox.d.ts","sourceRoot":"","sources":["../src/LoadingBox.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAyB,OAAO,EAAE,MAAM,eAAe,CAAC;AAE/D,eAAO,MAAM,UAAU,GAAI,OAAO;IAChC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,WAAW,CAAC,EAAE;QACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;CACH,sUA+CA,CAAC"}
package/LoadingBox.js ADDED
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, CircularProgress } from "@mui/material";
3
+ export const LoadingBox = (props) => {
4
+ const { children, loading, size = "small", sx, slotSxProps } = props;
5
+ if (!loading) {
6
+ return children;
7
+ }
8
+ return (_jsxs(Box, { sx: {
9
+ position: "relative",
10
+ width: "100%",
11
+ height: "100%",
12
+ minHeight: size === "medium" ? 24 : 16, // ensure some height for spinner
13
+ ...sx,
14
+ }, children: [_jsx(Box, { sx: {
15
+ position: "absolute",
16
+ top: "50%",
17
+ left: "50%",
18
+ transform: "translate(-50%, -50%)",
19
+ display: "flex",
20
+ alignItems: "center",
21
+ justifyContent: "center",
22
+ width: size === "medium" ? 24 : 16,
23
+ height: size === "medium" ? 24 : 16,
24
+ ...slotSxProps?.innerBox,
25
+ }, children: _jsx(CircularProgress, { size: size === "medium" ? 24 : 16, sx: {
26
+ ...slotSxProps?.progress,
27
+ } }) }), _jsx(Box, { sx: {
28
+ opacity: 0.3,
29
+ }, children: children })] }));
30
+ };
package/MediaTag.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { SxProps } from "@mui/material";
2
+ import * as wpCoreTypes from "@rnaga/wp-next-core/types";
3
+ export declare const MediaTag: <T extends wpCoreTypes.actions.Posts[number]>(props: {
4
+ post: T;
5
+ slotSxProps?: {
6
+ icon: SxProps;
7
+ };
8
+ }) => import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=MediaTag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaTag.d.ts","sourceRoot":"","sources":["../src/MediaTag.tsx"],"names":[],"mappings":"AACA,OAAO,EAAQ,OAAO,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,WAAW,MAAM,2BAA2B,CAAC;AAIzD,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO;IAC3E,IAAI,EAAE,CAAC,CAAC;IACR,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,OAAO,CAAC;KACf,CAAC;CACH,4CAsCA,CAAC"}
package/MediaTag.js ADDED
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import DocumentScannerOutlinedIcon from "@mui/icons-material/DocumentScannerOutlined";
3
+ import { Icon } from "@mui/material";
4
+ import { getMimeType } from "@rnaga/wp-next-core/client/utils/media";
5
+ export const MediaTag = (props) => {
6
+ const { post, slotSxProps } = props;
7
+ if (!post) {
8
+ return null;
9
+ }
10
+ const mimeType = getMimeType(post.guid);
11
+ const mediaType = mimeType.split("/")[0];
12
+ return mediaType == "image" ? (
13
+ // eslint-disable-next-line @next/next/no-img-element
14
+ _jsx("img", { "data-first-child": true, src: post.guid, loading: "lazy", alt: "", style: {
15
+ width: "100%",
16
+ height: "auto",
17
+ objectFit: "contain",
18
+ } })) : mediaType == "audio" ? (_jsxs("audio", { controls: true, "data-first-child": true, style: { maxHeight: 50 }, children: [_jsx("source", { src: post.guid }), "Your browser does not support the video tag."] })) : mediaType == "video" ? (_jsxs("video", { controls: true, "data-first-child": true, children: [_jsx("source", { src: post.guid }), "Your browser does not support the video tag."] })) : (_jsx(Icon, { "data-first-child": true, sx: slotSxProps?.icon, children: _jsx(DocumentScannerOutlinedIcon, { sx: slotSxProps?.icon }) }));
19
+ };
package/Modal.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Box, Modal as MuiModal, SxProps } from "@mui/material";
2
+ type ModalParameters = Omit<Parameters<typeof MuiModal>[0], "onClose"> & {
3
+ onClose: VoidFunction;
4
+ };
5
+ export declare const Modal: (props: ModalParameters) => import("react/jsx-runtime").JSX.Element;
6
+ export declare const ModalContent: (props: {
7
+ sx?: SxProps;
8
+ children: React.ReactNode;
9
+ } & Omit<Parameters<typeof Box>[0], "children" | "sx">) => import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=Modal.d.ts.map
package/Modal.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../src/Modal.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,GAAG,EAEH,KAAK,IAAI,QAAQ,EACjB,OAAO,EAER,MAAM,eAAe,CAAC;AAIvB,KAAK,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG;IACvE,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAQF,eAAO,MAAM,KAAK,GAAI,OAAO,eAAe,4CAkB3C,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO;IACL,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,4CAkEvD,CAAC"}
package/Modal.js ADDED
@@ -0,0 +1,65 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useContext, useEffect, useState } from "react";
3
+ import { Close } from "@mui/icons-material";
4
+ import { Box, IconButton, Modal as MuiModal, } from "@mui/material";
5
+ import { useWPTheme } from "./ThemeRegistry";
6
+ import { useWP } from "@rnaga/wp-next-core/client/wp";
7
+ const Context = createContext({});
8
+ export const Modal = (props) => {
9
+ const { children, open: muiOpen, onClose, ...rest } = props;
10
+ const [open, setOpen] = useState(false);
11
+ useEffect(() => {
12
+ setOpen(muiOpen);
13
+ }, [muiOpen]);
14
+ const handleClose = () => {
15
+ setOpen(false);
16
+ onClose();
17
+ };
18
+ return (_jsx(MuiModal, { open: open, onClose: handleClose, ...rest, children: _jsx(Context, { value: { open, setOpen, onClose }, children: children }) }));
19
+ };
20
+ export const ModalContent = (props) => {
21
+ const { sx, ...rest } = props;
22
+ const { setOpen, onClose } = useContext(Context);
23
+ const [isFullscreen, setIsFullscreen] = useState(false);
24
+ const { wpTheme } = useWPTheme();
25
+ const { viewport } = useWP();
26
+ useEffect(() => {
27
+ if (viewport.isMobile) {
28
+ setIsFullscreen(true);
29
+ }
30
+ else {
31
+ setIsFullscreen(false);
32
+ }
33
+ }, [viewport.isMobile]);
34
+ return (_jsx(Box, { sx: {
35
+ position: "absolute",
36
+ top: "50%",
37
+ left: "50%",
38
+ transform: "translate(-50%, -50%)",
39
+ bgcolor: "background.paper",
40
+ boxShadow: 24,
41
+ borderRadius: isFullscreen ? 0 : 1,
42
+ py: 4,
43
+ px: 2,
44
+ ...(isFullscreen && {
45
+ width: "100%",
46
+ height: "100%",
47
+ }),
48
+ ...sx,
49
+ }, ...rest, children: _jsxs(Box, { sx: {
50
+ position: "relative",
51
+ }, children: [_jsx(IconButton, { size: "small", onClick: (e) => {
52
+ setOpen(false);
53
+ onClose();
54
+ }, sx: {
55
+ position: "absolute",
56
+ top: isFullscreen ? -25 : -25,
57
+ right: isFullscreen ? -10 : -10,
58
+ zIndex: 1,
59
+ bgcolor: wpTheme.background.color,
60
+ border: "none",
61
+ ":hover": {
62
+ bgcolor: wpTheme.background.hoverColor,
63
+ },
64
+ }, children: _jsx(Close, { fontSize: "small" }) }), props.children] }) }));
65
+ };
@@ -0,0 +1,8 @@
1
+ export declare const ModalConfirm: (props: {
2
+ title?: string;
3
+ message: string | React.ReactNode;
4
+ callback: (confirm: boolean) => void;
5
+ open: boolean;
6
+ onClose?: () => void;
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=ModalConfirm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModalConfirm.d.ts","sourceRoot":"","sources":["../src/ModalConfirm.tsx"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,GAAI,OAAO;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,4CA0GA,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import WarningIcon from "@mui/icons-material/Warning";
4
+ import { Box, Divider } from "@mui/material";
5
+ import { useWP } from "@rnaga/wp-next-core/client/wp";
6
+ import { Button } from "./Button";
7
+ import { Modal, ModalContent } from "./Modal";
8
+ import { Typography } from "./Typography";
9
+ export const ModalConfirm = (props) => {
10
+ const { title = "Are you absolutely sure?", message, callback, onClose, } = props;
11
+ const { viewport } = useWP();
12
+ const [open, setOpen] = useState(props.open);
13
+ useEffect(() => {
14
+ console.log("changing open state to", props.open);
15
+ if (props.open !== open) {
16
+ setOpen(props.open);
17
+ }
18
+ }, [props.open]);
19
+ return (_jsx(Modal, { open: open, onClose: () => {
20
+ console.log("ConfirmModal onClose called, but no action taken");
21
+ setOpen(false);
22
+ onClose?.();
23
+ }, children: _jsxs(ModalContent, { "aria-labelledby": "nested-modal-title", "aria-describedby": "nested-modal-description", sx: {
24
+ minWidth: "40%",
25
+ ...(viewport.isMobile
26
+ ? {
27
+ top: "unset",
28
+ bottom: 0,
29
+ left: 0,
30
+ right: 0,
31
+ borderRadius: 0,
32
+ transform: "none",
33
+ maxWidth: "unset",
34
+ }
35
+ : {}),
36
+ }, children: [_jsxs(Box, { sx: {
37
+ display: "flex",
38
+ alignItems: "center",
39
+ gap: 1,
40
+ }, children: [_jsx(WarningIcon, {}), _jsx(Typography, { id: "nested-modal-title", size: "large", bold: true, children: title.length > 0 ? title : "Confirmation" })] }), _jsx(Divider, { sx: { my: 2 } }), _jsx(Typography, { id: "nested-modal-description", size: "large", component: "div", sx: {
41
+ mt: 1,
42
+ mb: 2,
43
+ whiteSpace: "pre-line",
44
+ }, children: message }), _jsxs(Box, { sx: {
45
+ mt: 1,
46
+ display: "flex",
47
+ gap: 1,
48
+ flexDirection: { xs: "column", sm: "row-reverse" },
49
+ }, children: [_jsx(Button, { size: "large", variant: "outlined", onClick: () => {
50
+ callback(true);
51
+ setOpen(false);
52
+ onClose?.();
53
+ }, color: "error", children: "Continue" }), _jsx(Button, { size: "large", variant: "outlined", color: "primary", onClick: () => {
54
+ callback(false);
55
+ setOpen(false);
56
+ onClose?.();
57
+ }, children: "Cancel" })] })] }) }));
58
+ };
@@ -0,0 +1,7 @@
1
+ import { Menu } from "@mui/material";
2
+ export declare const PopperMenu: (props: {
3
+ open: boolean;
4
+ children: React.ReactNode;
5
+ onClose: () => void;
6
+ } & Omit<React.ComponentProps<typeof Menu>, "open" | "onClose">) => import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=PopperMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PopperMenu.d.ts","sourceRoot":"","sources":["../src/PopperMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,IAAI,EAAE,MAAM,eAAe,CAAC;AAExD,eAAO,MAAM,UAAU,GACrB,OAAO;IACL,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,4CAgBhE,CAAC"}
package/PopperMenu.js ADDED
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Menu } from "@mui/material";
3
+ export const PopperMenu = (props) => {
4
+ const { ref, open, children, anchorEl, onClose, ...rest } = props;
5
+ return (_jsx(Menu, { anchorEl: anchorEl, open: open, onClose: onClose, ...rest, children: children }));
6
+ };
package/README.md ADDED
@@ -0,0 +1,292 @@
1
+ # WP-Next
2
+
3
+ WP-Next is built with [Next.js](https://nextjs.org/) and [WP-Node](https://github.com/rnaga/wp-node). It provides a modern **React-based Admin Dashboard** and utilities for building applications that interact directly with a WordPress database — **no PHP required**.
4
+
5
+ 👉 **View [Full Documentation](https://rnaga.github.io/wp-next/)**
6
+
7
+ <a href="https://vimeo.com/1112693769?share=copy#t=0" target="_blank" rel="noopener">
8
+ <img width="1200" height="699" alt="dashboard-vimeo" src="https://rnaga.github.io/wp-next/images/dashboard-vimeo.png" />
9
+ </a>
10
+
11
+ ## Quick Demo
12
+
13
+ Run a ready-made WP-Next example using Docker:
14
+
15
+ ```bash
16
+ docker run --rm --init -it --name wp-next-example -p 3000:3000 \
17
+ -v wp-next-example_public:/app/admin/public \
18
+ -v wp-next-example_db:/var/lib/mysql \
19
+ -v wp-next-example_html:/app/html \
20
+ rnagat/wp-next-example:latest
21
+ ```
22
+
23
+ Visit [http://localhost:3000/admin](http://localhost:3000/admin) and log in with:
24
+
25
+ ```text
26
+ Username: wp
27
+ Password: wp
28
+ ```
29
+
30
+ To stop and remove the running example container, use:
31
+
32
+ ```sh
33
+ docker stop wp-next-example
34
+ ```
35
+
36
+ ## Admin Dashboard
37
+
38
+ The main feature of WP-Next is the **Admin Dashboard**, a headless CMS that serves as an alternative to the traditional WordPress Admin Dashboard.
39
+
40
+ Out of the box, it includes:
41
+
42
+ - Posts & Pages
43
+ - Media
44
+ - Terms (Categories, Tags)
45
+ - Comments
46
+ - Profile & Settings
47
+ - Users and Roles
48
+ - Revisions
49
+
50
+ In **multisite mode**, it also supports:
51
+
52
+ - Sites
53
+ - Blogs (per-site content such as posts, media, comments)
54
+
55
+ ### Notes
56
+
57
+ Since WP-Next is entirely written in TypeScript and React, some WordPress features are **not supported**, including:
58
+
59
+ - WordPress Themes and appearance settings
60
+ - WordPress Block Editor (Gutenberg)
61
+ - WordPress template rendering APIs
62
+ - WordPress plugins
63
+
64
+ ## Core Libraries
65
+
66
+ - [`@rnaga/wp-node`](https://github.com/rnaga/wp-node) — TypeScript-first WordPress database integration.
67
+ - [`next`](https://nextjs.org/) — Next.js framework for SSR/SSG, routing, and APIs.
68
+ - [`@mui/material`](https://mui.com/) — Material UI component library.
69
+ - [`@tiptap/react`](https://tiptap.dev/), [`mui-tiptap`](https://github.com/sjdemartini/mui-tiptap) — TipTap rich-text editor with Material UI integration.
70
+
71
+ ## Installation
72
+
73
+ ### Prerequisites
74
+
75
+ WP-Next requires a running WordPress database. If you don’t already have WordPress installed, see the Prerequisites section in the WP-Node installation guide for instructions on running it with Docker:
76
+
77
+ https://rnaga.github.io/wp-node/docs/getting-started/installation#prerequisites
78
+
79
+ ### Initialize Project (Admin Dashboard)
80
+
81
+ WP-Next provides a CLI tool to initialize the Admin Dashboard. Run the following command and follow the prompts:
82
+
83
+ ```bash
84
+ npx @rnaga/wp-next-cli -- initAdmin
85
+ ```
86
+
87
+ Example setup prompts you may see:
88
+
89
+ ```text
90
+ ✔ Enter your database hostname: · localhost
91
+ ✔ Enter your database port: · 33306
92
+ ✔ Enter your database username: · wp
93
+ ✔ Enter your database password: · **
94
+ ✔ Enter your database name: · wordpress
95
+ ✔ Is it a multi-site? · No
96
+ ✔ Enter your static assets path: · public
97
+ ✔ Enter your Admin URL: · http://localhost:3000
98
+ ✔ Enter project path (What is your project named?): · admin
99
+ ```
100
+
101
+ The CLI will automatically install and configure:
102
+
103
+ - A Next.js project (App Router enabled) for the Admin Dashboard
104
+ - Pages and layouts required by the Admin Dashboard
105
+ - Configuration files and the `_wp/hooks` scaffolding
106
+
107
+ ### Run and Build the Admin Dashboard
108
+
109
+ Run in development mode:
110
+
111
+ ```bash
112
+ npm run dev
113
+ ```
114
+
115
+ Build and start for production:
116
+
117
+ ```bash
118
+ npm run build
119
+ npm run start
120
+ ```
121
+
122
+ For more on production deployment, refer to the Next.js deployment guide:
123
+
124
+ https://nextjs.org/docs/pages/getting-started/deploying
125
+
126
+ ## Hooks (Filter and Action)
127
+
128
+ WP-Next uses [WP-Node](https://github.com/rnaga/wp-node) hook system which is inspired by WordPress hooks but designed for TypeScript and Node.js. The system supports both filters (which transform data) and actions (which run side effects). Because WP-Node is TypeScript-first, hooks are type-safe and can be asynchronous — they are not directly compatible with WordPress core PHP hooks.
129
+
130
+ Key points:
131
+
132
+ - Filters: transform and return data; they may be async.
133
+ - Actions: perform side effects and do not return data.
134
+ - Hooks can be registered either with TypeScript decorators (static / application lifecycle) or with the functional HookCommand utilities (runtime / dynamic).
135
+
136
+ ### Frontend vs Backend hooks
137
+
138
+ When initialized, WP-Next generates a `_wp/hooks` directory where you can add your own hooks:
139
+
140
+ ```txt
141
+ hooks/
142
+ ├── client
143
+ │   └── index.tsx
144
+ └── server
145
+ ├── admin-media.hook.ts
146
+ ├── index.ts
147
+ ├── nextauth-providers.hook.ts
148
+ └── notifications.hook.ts
149
+ ```
150
+
151
+ #### Frontend Hooks
152
+
153
+ Frontend hooks (place under `_wp/hooks/client/`) are bundled into the Admin UI and run in the browser. Use them to register UI extensions such as sidebar menus, custom admin pages, or client-side theming. Frontend hooks must contain only client-safe code (no direct access to the filesystem, process env secrets, or server-only Node APIs).
154
+
155
+ #### Backend Hooks
156
+
157
+ Backend hooks (place under `_wp/hooks/server/`) run inside the server-side application/context. Use them for server responsibilities like media upload handling, authentication providers, email sending, or other integrations that require Node APIs, credentials, or synchronous server-side state.
158
+
159
+ For more details about hooks, how they work, and usage examples, see the WP-Node hooks documentation:
160
+
161
+ https://rnaga.github.io/wp-node/docs/concepts-features/hooks
162
+
163
+ ## Custom Admin Pages
164
+
165
+ You can extend the Admin Dashboard by registering **custom pages**:
166
+
167
+ Below are minimal, illustrative examples (a page component and a frontend hook) you can copy into `_wp/hooks/client/` and adapt to your project.
168
+
169
+ 1. **Create a React component** (`CustomPage.tsx`) to render your page.
170
+ 2. **Write a frontend hook** (`menu-custom.hook.tsx`) to add a sidebar menu and route.
171
+ 3. **Register the hook** in `_wp/hooks/client/index.tsx`.
172
+
173
+ Example menu item route:
174
+ `http://localhost:3000/admin/blog/custom`
175
+
176
+ This allows you to build fully custom interfaces inside the Admin while reusing the WP-Next shell.
177
+
178
+ Example code (illustrative — example usage)
179
+
180
+ These snippets show one way to implement `CustomPage.tsx` and `menu-custom.hook.tsx`. Adapt imports, types, and `capabilities` to your project; they are examples, not production-ready code.
181
+
182
+ CustomPage.tsx
183
+
184
+ ```tsx
185
+ import React from "react";
186
+ import Box from "@mui/material/Box";
187
+ import Typography from "@mui/material/Typography";
188
+
189
+ export const CustomPage = () => {
190
+ return (
191
+ <Box sx={{ p: 2 }}>
192
+ <Typography variant="h4" gutterBottom>
193
+ Custom Page
194
+ </Typography>
195
+
196
+ <Typography paragraph>
197
+ This is a simple custom admin page. Put your React UI here — forms,
198
+ lists, editor components, etc.
199
+ </Typography>
200
+
201
+ <ul>
202
+ <li>Example item 1</li>
203
+ <li>Example item 2</li>
204
+ </ul>
205
+ </Box>
206
+ );
207
+ };
208
+ ```
209
+
210
+ menu-custom.hook.tsx
211
+
212
+ ```tsx
213
+ "use client";
214
+
215
+ import { filter as clientFilter } from "@rnaga/wp-next-core/decorators";
216
+ import { hook } from "@rnaga/wp-node/decorators/hooks";
217
+ import CircleIcon from "@mui/icons-material/Circle";
218
+ import { CustomPage } from "./CustomPage";
219
+
220
+ @hook("next_admin_custom_menu")
221
+ export class MenuCustomHook {
222
+ @clientFilter("next_admin_menu")
223
+ hookFilter(adminMenus: any[] = [], segment?: string) {
224
+ // Only show in blog/dashboard segments
225
+ if (!["blog", "dashboard"].includes(segment || "")) {
226
+ return adminMenus;
227
+ }
228
+
229
+ const blogMenu = [
230
+ {
231
+ icon: <CircleIcon />,
232
+ displayOnSidebar: true,
233
+ component: <CustomPage />,
234
+ capabilities: ["read"], // control access
235
+ label: "Custom Page",
236
+ // final route: /admin/blog/custom
237
+ path: `/${"blog"}/custom`,
238
+ },
239
+ ];
240
+
241
+ return [...adminMenus, ...blogMenu];
242
+ }
243
+ }
244
+ ```
245
+
246
+ index.tsx (register hooks)
247
+
248
+ ```ts
249
+ import { getDefaultAdminHooks } from "@rnaga/wp-next-admin/client/utils";
250
+ import { MenuCustomHook } from "./menu-custom.hook";
251
+
252
+ // include defaults first, then your custom hook
253
+ export const hooks = [...getDefaultAdminHooks(), MenuCustomHook];
254
+ ```
255
+
256
+ Summary and quick how-to
257
+
258
+ - Prerequisite: WP-Next Admin initialized (project creates `_wp/hooks/` on first run).
259
+
260
+ - Key files (place under `_wp/hooks/client/`):
261
+
262
+ - `CustomPage.tsx` — minimal React page component that renders when the route is visited.
263
+ - `menu-custom.hook.tsx` — frontend hook that adds a sidebar menu entry and maps a path (e.g. `/admin/blog/custom`) to your component. Use the `@hook(...)` class decorator and a client filter such as `@clientFilter('next_admin_menu')` to contribute menu items.
264
+ - `index.tsx` — export the frontend hooks array. Include defaults first, then your custom hook: `export const hooks = [...getDefaultAdminHooks(), MenuCustomHook];`
265
+
266
+ - Important notes:
267
+
268
+ - Admin routes are segmented (e.g. `dashboard`, `blog`). Hooks often check/normalize the current segment so the final URL becomes something like `/admin/blog/custom`.
269
+ - Use `capabilities` on menu items (for example `['read']` or `['edit_posts']`) to restrict access.
270
+ - Frontend hooks run in the browser bundle — avoid Node-only APIs, filesystem access, or secrets in client hooks.
271
+
272
+ - Quick steps:
273
+
274
+ 1. Create `_wp/hooks/client/CustomPage.tsx` with your React UI.
275
+ 2. Add `_wp/hooks/client/menu-custom.hook.tsx` to register the menu item and route (set `component`, `path`, and `capabilities`).
276
+ 3. Add your hook to `_wp/hooks/client/index.tsx` so the Admin shell loads it.
277
+ 4. Run in dev or build for production.
278
+
279
+ - Run:
280
+
281
+ ```bash
282
+ npm run dev
283
+ # or for production
284
+ npm run build
285
+ npm run start
286
+ ```
287
+
288
+ Example menu route: `http://localhost:3000/admin/blog/custom`
289
+
290
+ ## License
291
+
292
+ MIT