@rnaga/wp-next-ui 1.1.10 → 1.2.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 (54) hide show
  1. package/Button.js +1 -1
  2. package/DateTimePicker.d.ts.map +1 -1
  3. package/DateTimePicker.js +32 -25
  4. package/DraggableBox.d.ts +1 -1
  5. package/DraggableBox.d.ts.map +1 -1
  6. package/InputSearch.d.ts.map +1 -1
  7. package/InputSearch.js +3 -1
  8. package/Loading.d.ts +1 -1
  9. package/Loading.d.ts.map +1 -1
  10. package/LoadingBox.d.ts +1 -1
  11. package/LoadingBox.d.ts.map +1 -1
  12. package/MediaTag.d.ts +1 -1
  13. package/MediaTag.d.ts.map +1 -1
  14. package/MediaTag.js +1 -3
  15. package/README.md +100 -218
  16. package/SelectAutocomplete.d.ts +1109 -1077
  17. package/SelectAutocomplete.d.ts.map +1 -1
  18. package/SelectAutocomplete.js +1 -1
  19. package/SelectWPPost.d.ts.map +1 -1
  20. package/SelectWPPost.js +4 -1
  21. package/SelectWPTerm.d.ts.map +1 -1
  22. package/SelectWPTerm.js +4 -1
  23. package/SelectWPUser.d.ts.map +1 -1
  24. package/SelectWPUser.js +4 -1
  25. package/SortableList.js +1 -1
  26. package/Tabs.d.ts +1 -1
  27. package/Tabs.d.ts.map +1 -1
  28. package/ThemeRegistry.d.ts +2 -2
  29. package/ThemeRegistry.d.ts.map +1 -1
  30. package/Typography.d.ts +3 -2
  31. package/Typography.d.ts.map +1 -1
  32. package/Typography.js +23 -8
  33. package/font/import-fonts.d.ts +5 -0
  34. package/font/import-fonts.d.ts.map +1 -0
  35. package/font/import-fonts.js +4 -0
  36. package/hooks/use-form-data.d.ts +3 -3
  37. package/hooks/use-scheme-toggle.d.ts +1 -1
  38. package/list/ListTable.d.ts +3 -3
  39. package/list/ListTable.d.ts.map +1 -1
  40. package/list/Pagination.d.ts +1 -1
  41. package/list/Pagination.d.ts.map +1 -1
  42. package/media/MediaGridForm.d.ts +1 -1
  43. package/media/MediaGridForm.d.ts.map +1 -1
  44. package/media/MediaThumbnail.d.ts +1 -1
  45. package/media/MediaThumbnail.d.ts.map +1 -1
  46. package/media/MediaThumbnail.js +1 -3
  47. package/media/MediaUpload.js +1 -1
  48. package/media-selector/MediaSelectorList.js +1 -1
  49. package/media-selector/MediaSelectorPreview.d.ts +1 -1
  50. package/media-selector/MediaSelectorPreview.d.ts.map +1 -1
  51. package/media-selector/index.js +2 -1
  52. package/package.json +5 -4
  53. package/portal/use-portal.d.ts +1 -1
  54. package/portal/use-portal.d.ts.map +1 -1
package/Button.js CHANGED
@@ -5,7 +5,7 @@ import { useWPTheme } from "./ThemeRegistry";
5
5
  export const Button = (props) => {
6
6
  const { children, size, component, bold, loading, color, disabled, endIcon, ...rest } = props;
7
7
  const { wpTheme } = useWPTheme();
8
- return (_jsx(MuiButton, { ...rest, component: component, variant: "contained", size: "small", disableElevation: true, disabled: loading || disabled === true, sx: {
8
+ return (_jsx(MuiButton, { ...rest, ...(component !== undefined ? { component } : {}), variant: "contained", size: "small", disableElevation: true, disabled: loading || disabled === true, sx: {
9
9
  textTransform: "none",
10
10
  fontSize: size === "large" ? 16 : size === "medium" ? 14 : 12,
11
11
  ...(bold ? { fontWeight: "bold" } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"DateTimePicker.d.ts","sourceRoot":"","sources":["../src/DateTimePicker.tsx"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,GAAI,OAAO;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrC,4CAiDA,CAAC"}
1
+ {"version":3,"file":"DateTimePicker.d.ts","sourceRoot":"","sources":["../src/DateTimePicker.tsx"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,GAAI,OAAO;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrC,4CAkDA,CAAC"}
package/DateTimePicker.js CHANGED
@@ -7,39 +7,46 @@ import { useWPTheme } from "./ThemeRegistry";
7
7
  export const DateTimePicker = (props) => {
8
8
  const { value, onChange, size } = props;
9
9
  const { wpTheme } = useWPTheme();
10
- return (_jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, children: _jsx(MuiDateTimePicker, { value: dayjs(value), onChange: (newValue) => {
10
+ const fontSize = size === "large" ? 16 : size === "medium" ? 14 : 12;
11
+ const height = size === "large" ? 36 : size === "medium" ? 32 : 24;
12
+ return (_jsx(LocalizationProvider, { dateAdapter: AdapterDayjs, children: _jsx(MuiDateTimePicker
13
+ /**
14
+ * Pass null for empty/invalid values — dayjs(undefined) returns "now"
15
+ * which misleads the picker when no date has been set.
16
+ */
17
+ , {
18
+ /**
19
+ * Pass null for empty/invalid values — dayjs(undefined) returns "now"
20
+ * which misleads the picker when no date has been set.
21
+ */
22
+ value: value ? dayjs(value) : null, onChange: (newValue) => {
11
23
  onChange && onChange(newValue?.toDate() || "");
12
24
  }, slotProps: {
13
- textField: {
14
- size: "small",
15
- slotProps: {
16
- input: { disableUnderline: true, sx: { fontSize: 0.1 } },
17
- },
25
+ /**
26
+ * In MUI X v9 the textField slot was removed; use field.sx instead.
27
+ * Targets MuiPickersOutlinedInput-root (replaces MuiOutlinedInput-root).
28
+ */
29
+ field: {
18
30
  sx: {
19
- "& .MuiInputBase-input": {
20
- py: 0.5,
21
- px: 1,
31
+ fontSize,
32
+ height,
33
+ border: `1px solid ${wpTheme.border.color}`,
34
+ borderRadius: 1,
35
+ "& .MuiPickersOutlinedInput-root": {
36
+ height: "100%",
37
+ fontSize,
38
+ "& fieldset": { border: "none" },
39
+ "&.Mui-focused fieldset": { border: "none" },
40
+ "&:hover fieldset": { border: "none" },
22
41
  },
23
- "& .MuiOutlinedInput-root": {
24
- fontSize: size === "large" ? 16 : size === "medium" ? 14 : 12,
25
- height: size === "large" ? 36 : size == "medium" ? 32 : 24,
26
- border: `1px solid ${wpTheme.border.color}`,
27
- "& fieldset": {
28
- border: "none",
29
- },
30
- "&.Mui-focused fieldset": {
31
- border: "none",
32
- },
33
- "&:hover fieldset": {
34
- border: "none",
35
- },
42
+ "& .MuiPickersSectionList-root": {
43
+ py: 0,
44
+ px: 1,
36
45
  },
37
46
  "& .MuiSvgIcon-root": {
38
47
  fontSize: size === "large" ? 26 : size === "medium" ? 22 : 18,
39
48
  },
40
49
  },
41
50
  },
42
- }, sx: {
43
- width: "100%",
44
- } }) }));
51
+ }, sx: { width: "100%" } }) }));
45
52
  };
package/DraggableBox.d.ts CHANGED
@@ -43,6 +43,6 @@ export declare const DraggableBox: (props: {
43
43
  placement?: "target" | "left";
44
44
  resizable?: boolean;
45
45
  onResize?: (width: number, height: number, event?: Event) => void;
46
- }) => import("react/jsx-runtime").JSX.Element;
46
+ }) => import("react/jsx-runtime").JSX.Element | null;
47
47
  export {};
48
48
  //# sourceMappingURL=DraggableBox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DraggableBox.d.ts","sourceRoot":"","sources":["../src/DraggableBox.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,EACZ,SAAS,EAKV,MAAM,OAAO,CAAC;AACf,OAAO,EAAmB,OAAO,EAAE,MAAM,eAAe,CAAC;AAOzD,KAAK,WAAW,GAAG;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO;IAClC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC,GAAG,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACpC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;CACnE,4CA6cA,CAAC"}
1
+ {"version":3,"file":"DraggableBox.d.ts","sourceRoot":"","sources":["../src/DraggableBox.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,EACZ,SAAS,EAKV,MAAM,OAAO,CAAC;AACf,OAAO,EAAmB,OAAO,EAAE,MAAM,eAAe,CAAC;AAOzD,KAAK,WAAW,GAAG;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO;IAClC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC,GAAG,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACpC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;CACnE,mDA6cA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"InputSearch.d.ts","sourceRoot":"","sources":["../src/InputSearch.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAKxC,eAAO,MAAM,WAAW,GAAI,OAAO;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,EAAE,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC7E,4CA6CA,CAAC"}
1
+ {"version":3,"file":"InputSearch.d.ts","sourceRoot":"","sources":["../src/InputSearch.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAKxC,eAAO,MAAM,WAAW,GAAI,OAAO;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,EAAE,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC7E,4CA+CA,CAAC"}
package/InputSearch.js CHANGED
@@ -9,7 +9,9 @@ export const InputSearch = (props) => {
9
9
  const ref = useRef(null);
10
10
  const handleClear = () => {
11
11
  updateRouter({ search: "" });
12
- ref.current.value = "";
12
+ if (ref.current) {
13
+ ref.current.value = "";
14
+ }
13
15
  };
14
16
  const handleChange = (value, e) => {
15
17
  if (props.onChange) {
package/Loading.d.ts CHANGED
@@ -3,5 +3,5 @@ export declare const Loading: (props: {
3
3
  children?: React.ReactNode;
4
4
  loading: boolean;
5
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;
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> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
7
7
  //# sourceMappingURL=Loading.d.ts.map
package/Loading.d.ts.map CHANGED
@@ -1 +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"}
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,4WA+CA,CAAC"}
package/LoadingBox.d.ts CHANGED
@@ -8,5 +8,5 @@ export declare const LoadingBox: (props: {
8
8
  innerBox?: SxProps;
9
9
  progress?: SxProps;
10
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;
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> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
12
12
  //# sourceMappingURL=LoadingBox.d.ts.map
@@ -1 +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"}
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,4WA+CA,CAAC"}
package/MediaTag.d.ts CHANGED
@@ -5,5 +5,5 @@ export declare const MediaTag: <T extends wpCoreTypes.actions.Posts[number]>(pro
5
5
  slotSxProps?: {
6
6
  icon: SxProps;
7
7
  };
8
- }) => import("react/jsx-runtime").JSX.Element;
8
+ }) => import("react/jsx-runtime").JSX.Element | null;
9
9
  //# sourceMappingURL=MediaTag.d.ts.map
package/MediaTag.d.ts.map CHANGED
@@ -1 +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"}
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,mDAsCA,CAAC"}
package/MediaTag.js CHANGED
@@ -9,9 +9,7 @@ export const MediaTag = (props) => {
9
9
  }
10
10
  const mimeType = getMimeType(post.guid);
11
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: {
12
+ return mediaType == "image" ? (_jsx("img", { "data-first-child": true, src: post.guid, loading: "lazy", alt: "", style: {
15
13
  width: "100%",
16
14
  height: "auto",
17
15
  objectFit: "contain",
package/README.md CHANGED
@@ -1,291 +1,173 @@
1
1
  # WP-Next
2
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**.
3
+ WP-Next is built with [Next.js](https://nextjs.org/) and [WP-Node](https://github.com/rnaga/wp-node). It provides two complementary products for building WordPress-powered applications where every layer is written from scratch in TypeScript and React — **no PHP involved**.
4
4
 
5
- 👉 **View [Full Documentation](https://rnaga.github.io/wp-next/)**
5
+ ---
6
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>
7
+ ## 📖 [Full Documentation → rnaga.github.io/wp-next](https://rnaga.github.io/wp-next/)
10
8
 
11
- ## Quick Demo
9
+ > For guides, concepts, and examples, the documentation site is the best starting point.
12
10
 
13
- Run a ready-made WP-Next example using Docker:
11
+ ---
14
12
 
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
- ```
13
+ ## WP-Next Editor
22
14
 
23
- Visit [http://localhost:3000/admin](http://localhost:3000/admin) and log in with:
15
+ WP-Next Editor is a visual, drag-and-drop page editor for building public-facing pages directly connected to your WordPress database. Pages are stored as structured [Lexical](https://lexical.dev/docs/intro) JSON in the WordPress database — making them version-controllable, programmatically manipulable, and AI-ready.
24
16
 
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
17
+ <a href="https://vimeo.com/1185738064?share=copy#t=0" target="_blank" rel="noopener">
18
+ <img width="1200" height="699" alt="WP-Next Editor canvas demo" src="https://rnaga.github.io/wp-next/assets/editor/canvas/canvas.png" />
19
+ </a>
74
20
 
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:
21
+ ### Key Features
76
22
 
77
- https://rnaga.github.io/wp-node/docs/getting-started/installation#prerequisites
23
+ - **Drag-and-drop canvas** — build pages visually with a live preview. Select, resize, nest, and animate elements directly on the canvas.
24
+ - **Responsive design** — set per-device breakpoints (desktop, tablet, mobile) and CSS states (hover, focus, etc.). Each device gets its own `@media` query at render time.
25
+ - **Dynamic data binding** — pull posts, users, taxonomies, and options directly from the WordPress database into any element. No custom API endpoints required.
26
+ - **Widget system** — embed sub-templates (widgets) inside other templates for reusable headers, footers, and components. Widget variants let the same widget render different content per embedding.
27
+ - **CSS variables** — define design tokens at the template level and reference them across all elements for consistent theming.
28
+ - **Animations** — attach CSS keyframe animations (98 Animate.css presets) to any element, triggered by hover, click, scroll, and more.
29
+ - **JSON editor** — edit the raw Lexical JSON directly in a built-in code editor for precise control over template structure.
30
+ - **Save history** — create and manage template save points with preview and restore support.
78
31
 
79
- ### Initialize Project (Admin Dashboard)
32
+ ### Quick Demo
80
33
 
81
- WP-Next provides a CLI tool to initialize the Admin Dashboard. Run the following command and follow the prompts:
34
+ Run a ready-made WP-Next Editor example using Docker:
82
35
 
83
36
  ```bash
84
- npx @rnaga/wp-next-cli -- initAdmin
37
+ docker run --rm --init -it --name wp-next-editor-example -p 3000:3000 \
38
+ -v wp-next-editor_public:/app/editor/public \
39
+ -v wp-next-editor_db:/var/lib/mysql \
40
+ rnagat/wp-next-editor-example:latest
85
41
  ```
86
42
 
87
- Example setup prompts you may see:
43
+ Log in with:
88
44
 
89
45
  ```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
46
+ Username: wp
47
+ Password: wp
99
48
  ```
100
49
 
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
50
+ - Editor: [http://localhost:3000/admin/1/editor](http://localhost:3000/admin/1/editor)
51
+ - Admin Dashboard: [http://localhost:3000/admin](http://localhost:3000/admin)
106
52
 
107
- ### Run and Build the Admin Dashboard
108
-
109
- Run in development mode:
53
+ To stop the container:
110
54
 
111
55
  ```bash
112
- npm run dev
56
+ docker stop wp-next-editor-example
113
57
  ```
114
58
 
115
- Build and start for production:
59
+ ### Initialize the Editor
116
60
 
117
61
  ```bash
118
- npm run build
119
- npm run start
62
+ npx @rnaga/wp-next-cli -- initEditor
120
63
  ```
121
64
 
122
- For more on production deployment, refer to the Next.js deployment guide:
65
+ See the [Editor Installation guide](https://rnaga.github.io/wp-next/docs/editor/installation) for the full setup walkthrough.
123
66
 
124
- https://nextjs.org/docs/pages/getting-started/deploying
67
+ > `wp-next-editor` includes `wp-next-admin` out of the box. See [WP-Next Admin](#wp-next-admin) below for what it provides.
125
68
 
126
- ## Hooks (Filter and Action)
69
+ ### AI-Powered Template Authoring — Built-in Agent Skills
127
70
 
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.
71
+ WP-Next Editor ships with a built-in **[Agent Skill](https://agentskills.io/home)** (`/wp-next-editor-template`) that lets you build and modify templates using natural-language prompts. All templates are stored as Lexical JSON, so AI agents can read, write, and transform them directly.
129
72
 
130
- Key points:
73
+ [Agent Skills](https://agentskills.io/home) is an open standard supported by Claude Code, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, VS Code, and more. Install the skill once and use it with whichever coding agent you prefer.
131
74
 
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).
75
+ The skill supports four modes:
135
76
 
136
- ### Frontend vs Backend hooks
77
+ | Mode | What it does |
78
+ | --------- | ----------------------------------------------------------- |
79
+ | `create` | Scaffold a new template from a natural-language description |
80
+ | `update` | Modify an existing template based on a prompt |
81
+ | `convert` | Convert HTML/CSS into a Lexical JSON template |
82
+ | `help` | Describe available nodes, styles, and patterns |
137
83
 
138
- When initialized, WP-Next generates a `_wp/hooks` directory where you can add your own hooks:
84
+ Install the skill with:
139
85
 
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
86
+ ```bash
87
+ npx @rnaga/wp-next-cli -- editor agentSkills add
149
88
  ```
150
89
 
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).
90
+ Example prompt:
154
91
 
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
92
+ ```
93
+ /wp-next-editor-template create src/templates/home.json "A hero section with a full-width background image, centered headline, subtitle, and a CTA button"
94
+ ```
162
95
 
163
- ## Custom Admin Pages
96
+ See [Using AI](https://rnaga.github.io/wp-next/docs/editor/concepts-features/using-ai) for installation details and more examples.
164
97
 
165
- You can extend the Admin Dashboard by registering **custom pages**:
98
+ ---
166
99
 
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.
100
+ ## WP-Next Admin
168
101
 
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`.
102
+ WP-Next Admin is a **React-based Admin Dashboard** a headless CMS that serves as a modern alternative to the traditional WordPress Admin Dashboard.
172
103
 
173
- Example menu item route:
174
- `http://localhost:3000/admin/blog/custom`
104
+ <a href="https://vimeo.com/1112693769?share=copy#t=0" target="_blank" rel="noopener">
105
+ <img width="1200" height="699" alt="WP-Next Admin dashboard demo" src="https://rnaga.github.io/wp-next/images/dashboard-vimeo.png" />
106
+ </a>
175
107
 
176
- This allows you to build fully custom interfaces inside the Admin while reusing the WP-Next shell.
108
+ ### Key Features
177
109
 
178
- Example code (illustrative example usage)
110
+ Out of the box, it includes:
179
111
 
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.
112
+ - Posts & Pages
113
+ - Media
114
+ - Terms (Categories, Tags)
115
+ - Comments
116
+ - Profile & Settings
117
+ - Users and Roles
118
+ - Revisions
181
119
 
182
- CustomPage.tsx
120
+ In **multisite mode**, it also supports:
183
121
 
184
- ```tsx
185
- import React from "react";
186
- import Box from "@mui/material/Box";
187
- import Typography from "@mui/material/Typography";
122
+ - Sites
123
+ - Blogs (per-site content such as posts, media, comments)
188
124
 
189
- export const CustomPage = () => {
190
- return (
191
- <Box sx={{ p: 2 }}>
192
- <Typography variant="h4" gutterBottom>
193
- Custom Page
194
- </Typography>
125
+ ### Quick Demo
195
126
 
196
- <Typography paragraph>
197
- This is a simple custom admin page. Put your React UI here — forms,
198
- lists, editor components, etc.
199
- </Typography>
127
+ Run a ready-made WP-Next example using Docker:
200
128
 
201
- <ul>
202
- <li>Example item 1</li>
203
- <li>Example item 2</li>
204
- </ul>
205
- </Box>
206
- );
207
- };
129
+ ```bash
130
+ docker run --rm --init -it --name wp-next-example -p 3000:3000 \
131
+ -v wp-next-example_public:/app/admin/public \
132
+ -v wp-next-example_db:/var/lib/mysql \
133
+ -v wp-next-example_html:/app/html \
134
+ rnagat/wp-next-example:latest
208
135
  ```
209
136
 
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
- ```
137
+ Visit [http://localhost:3000/admin](http://localhost:3000/admin) and log in with:
245
138
 
246
- index.tsx (register hooks)
139
+ ```text
140
+ Username: wp
141
+ Password: wp
142
+ ```
247
143
 
248
- ```ts
249
- import { getDefaultAdminHooks } from "@rnaga/wp-next-admin/client/utils";
250
- import { MenuCustomHook } from "./menu-custom.hook";
144
+ To stop the container:
251
145
 
252
- // include defaults first, then your custom hook
253
- export const hooks = [...getDefaultAdminHooks(), MenuCustomHook];
146
+ ```bash
147
+ docker stop wp-next-example
254
148
  ```
255
149
 
256
- Summary and quick how-to
257
-
258
- - Prerequisite: WP-Next Admin initialized (project creates `_wp/hooks/` on first run).
150
+ ### Initialize the Admin Dashboard
259
151
 
260
- - Key files (place under `_wp/hooks/client/`):
152
+ ```bash
153
+ npx @rnaga/wp-next-cli -- initAdmin
154
+ ```
261
155
 
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];`
156
+ See the [Admin Getting Started guide](https://rnaga.github.io/wp-next/docs/admin/getting-started) for the full setup walkthrough.
265
157
 
266
- - Important notes:
158
+ ### Extensibility
267
159
 
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.
160
+ WP-Next Admin supports **custom pages** and a **hook system** (filters and actions) inspired by WordPress hooks but built for TypeScript and Node.js. Frontend hooks extend the Admin UI in the browser; backend hooks handle server-side concerns such as authentication, media uploads, and integrations.
271
161
 
272
- - Quick steps:
162
+ See [Hooks](https://rnaga.github.io/wp-next/docs/admin/concepts-features/hooks) and [Custom Admin Pages](https://rnaga.github.io/wp-next/docs/admin/concepts-features/custom-pages) in the documentation.
273
163
 
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.
164
+ ---
278
165
 
279
- - Run:
166
+ ## Prerequisites
280
167
 
281
- ```bash
282
- npm run dev
283
- # or for production
284
- npm run build
285
- npm run start
286
- ```
168
+ Both products require a running WordPress database. If you don't already have WordPress installed, see the [WP-Node installation guide](https://rnaga.github.io/wp-node/docs/getting-started/installation#prerequisites) for instructions on running it with Docker.
287
169
 
288
- Example menu route: `http://localhost:3000/admin/blog/custom`
170
+ ---
289
171
 
290
172
  ## License
291
173