@wordpress/boot 0.1.1-next.2f1c7c01b.0 → 0.2.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/build-module/components/app/index.js +22 -4
- package/build-module/components/app/index.js.map +2 -2
- package/build-module/components/app/router.js +26 -16
- package/build-module/components/app/router.js.map +2 -2
- package/build-module/components/canvas/back-button.js +176 -0
- package/build-module/components/canvas/back-button.js.map +7 -0
- package/build-module/components/canvas/index.js +51 -0
- package/build-module/components/canvas/index.js.map +7 -0
- package/build-module/components/root/index.js +68 -14
- package/build-module/components/root/index.js.map +2 -2
- package/build-module/components/root/single-page.js +167 -0
- package/build-module/components/root/single-page.js.map +7 -0
- package/build-module/components/save-panel/index.js +36 -0
- package/build-module/components/save-panel/index.js.map +7 -0
- package/build-module/components/save-panel/use-save-shortcut.js +55 -0
- package/build-module/components/save-panel/use-save-shortcut.js.map +7 -0
- package/build-module/index.js +213 -416
- package/build-module/index.js.map +2 -2
- package/build-style/style-rtl.css +209 -413
- package/build-style/style.css +209 -413
- package/build-types/components/app/index.d.ts +6 -1
- package/build-types/components/app/index.d.ts.map +1 -1
- package/build-types/components/app/router.d.ts +3 -1
- package/build-types/components/app/router.d.ts.map +1 -1
- package/build-types/components/canvas/back-button.d.ts +13 -0
- package/build-types/components/canvas/back-button.d.ts.map +1 -0
- package/build-types/components/canvas/index.d.ts +17 -0
- package/build-types/components/canvas/index.d.ts.map +1 -0
- package/build-types/components/navigation/path-matching.d.ts.map +1 -1
- package/build-types/components/root/index.d.ts.map +1 -1
- package/build-types/components/root/single-page.d.ts +7 -0
- package/build-types/components/root/single-page.d.ts.map +1 -0
- package/build-types/components/save-panel/index.d.ts +2 -0
- package/build-types/components/save-panel/index.d.ts.map +1 -0
- package/build-types/components/save-panel/use-save-shortcut.d.ts +10 -0
- package/build-types/components/save-panel/use-save-shortcut.d.ts.map +1 -0
- package/build-types/index.d.ts +1 -1
- package/build-types/index.d.ts.map +1 -1
- package/build-types/store/types.d.ts +9 -0
- package/build-types/store/types.d.ts.map +1 -1
- package/package.json +20 -17
- package/src/components/app/index.tsx +30 -4
- package/src/components/app/router.tsx +45 -21
- package/src/components/canvas/back-button.scss +62 -0
- package/src/components/canvas/back-button.tsx +86 -0
- package/src/components/canvas/index.tsx +79 -0
- package/src/components/root/index.tsx +30 -6
- package/src/components/root/single-page.tsx +64 -0
- package/src/components/root/style.scss +36 -1
- package/src/components/save-panel/index.tsx +35 -0
- package/src/components/save-panel/use-save-shortcut.ts +67 -0
- package/src/index.tsx +1 -1
- package/src/store/types.ts +10 -0
- package/src/style.scss +43 -0
- package/tsconfig.json +2 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { MenuItem, Route } from '../../store/types';
|
|
2
|
-
export declare function init({ menuItems, routes, }: {
|
|
2
|
+
export declare function init({ mountId, menuItems, routes, }: {
|
|
3
|
+
mountId: string;
|
|
3
4
|
menuItems?: MenuItem[];
|
|
4
5
|
routes?: Route[];
|
|
5
6
|
}): Promise<void>;
|
|
7
|
+
export declare function initSinglePage({ mountId, routes, }: {
|
|
8
|
+
mountId: string;
|
|
9
|
+
routes?: Route[];
|
|
10
|
+
}): Promise<void>;
|
|
6
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/app/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/app/index.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAQzD,wBAAsB,IAAI,CAAE,EAC3B,OAAO,EACP,SAAS,EACT,MAAM,GACN,EAAE;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB,iBAmBA;AAED,wBAAsB,cAAc,CAAE,EACrC,OAAO,EACP,MAAM,GACN,EAAE;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB,iBAeA"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
1
2
|
import type { Route } from '../../store/types';
|
|
2
3
|
interface RouterProps {
|
|
3
4
|
routes: Route[];
|
|
5
|
+
rootComponent?: ComponentType;
|
|
4
6
|
}
|
|
5
|
-
export default function Router({ routes }: RouterProps): import("react").JSX.Element;
|
|
7
|
+
export default function Router({ routes, rootComponent, }: RouterProps): import("react").JSX.Element;
|
|
6
8
|
export {};
|
|
7
9
|
//# sourceMappingURL=router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/components/app/router.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/components/app/router.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAa3C,OAAO,KAAK,EAAE,KAAK,EAAsB,MAAM,mBAAmB,CAAC;AA2JnE,UAAU,WAAW;IACpB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAAE,EAC/B,MAAM,EACN,aAAoB,GACpB,EAAE,WAAW,+BAgCb"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import './back-button.scss';
|
|
2
|
+
/**
|
|
3
|
+
* Back button component that appears in full-screen canvas mode.
|
|
4
|
+
* Matches next-admin's SiteIconBackButton design.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} props Component props
|
|
7
|
+
* @param {number} props.length Number of BackButton fills (from Slot)
|
|
8
|
+
* @return Back button with slide and hover animations
|
|
9
|
+
*/
|
|
10
|
+
export default function BootBackButton({ length }: {
|
|
11
|
+
length: number;
|
|
12
|
+
}): import("react").JSX.Element | null;
|
|
13
|
+
//# sourceMappingURL=back-button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"back-button.d.ts","sourceRoot":"","sources":["../../../src/components/canvas/back-button.tsx"],"names":[],"mappings":"AAgBA,OAAO,oBAAoB,CAAC;AAkB5B;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,sCA2CrE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { CanvasData } from '../../store/types';
|
|
5
|
+
interface CanvasProps {
|
|
6
|
+
canvas: CanvasData;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Canvas component that dynamically loads and renders the lazy editor.
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} props - Component props
|
|
12
|
+
* @param {Object} props.canvas - Canvas data containing postType and postId
|
|
13
|
+
* @return Canvas surface with editor
|
|
14
|
+
*/
|
|
15
|
+
export default function Canvas({ canvas }: CanvasProps): import("react").JSX.Element;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/canvas/index.tsx"],"names":[],"mappings":"AAMA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,UAAU,WAAW;IACpB,MAAM,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAE,EAAE,MAAM,EAAE,EAAE,WAAW,+BAuDtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path-matching.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/path-matching.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAqClD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"path-matching.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/path-matching.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAqClD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAC/B,aAAa,MAAM,EACnB,WAAW,QAAQ,EAAE,KACnB,QAAQ,GAAG,IAyBb,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC/B,IAAI,MAAM,GAAG,SAAS,EACtB,WAAW,QAAQ,EAAE,KACnB,MAAM,GAAG,SA0BX,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC9B,IAAI,MAAM,GAAG,SAAS,EACtB,WAAW,QAAQ,EAAE,KACnB,MAAM,GAAG,SAsBX,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/root/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/root/index.tsx"],"names":[],"mappings":"AAqBA,OAAO,cAAc,CAAC;AAItB,MAAM,CAAC,OAAO,UAAU,IAAI,gCAwC3B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import './style.scss';
|
|
2
|
+
/**
|
|
3
|
+
* Root component for single page mode (no sidebar).
|
|
4
|
+
* Used when rendering pages within wp-admin without taking over the full page.
|
|
5
|
+
*/
|
|
6
|
+
export default function RootSinglePage(): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=single-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"single-page.d.ts","sourceRoot":"","sources":["../../../src/components/root/single-page.tsx"],"names":[],"mappings":"AAoBA,OAAO,cAAc,CAAC;AAItB;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,gCAmCrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/save-panel/index.tsx"],"names":[],"mappings":"AAaA,MAAM,CAAC,OAAO,UAAU,SAAS,wCAqBhC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register the save keyboard shortcut in view mode.
|
|
3
|
+
*
|
|
4
|
+
* @param param0 Object containing the function to open the save panel.
|
|
5
|
+
* @param param0.openSavePanel Function to open the save panel.
|
|
6
|
+
*/
|
|
7
|
+
export default function useSaveShortcut({ openSavePanel, }: {
|
|
8
|
+
openSavePanel: () => void;
|
|
9
|
+
}): void;
|
|
10
|
+
//# sourceMappingURL=use-save-shortcut.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-save-shortcut.d.ts","sourceRoot":"","sources":["../../../src/components/save-panel/use-save-shortcut.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAE,EACxC,aAAa,GACb,EAAE;IACF,aAAa,EAAE,MAAM,IAAI,CAAC;CAC1B,QAwCA"}
|
package/build-types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -33,6 +33,14 @@ export interface RouteLoaderContext {
|
|
|
33
33
|
params: Record<string, string>;
|
|
34
34
|
search: Record<string, unknown>;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Canvas data returned by route's canvas function.
|
|
38
|
+
*/
|
|
39
|
+
export interface CanvasData {
|
|
40
|
+
postType: string;
|
|
41
|
+
postId: string;
|
|
42
|
+
isPreview?: boolean;
|
|
43
|
+
}
|
|
36
44
|
/**
|
|
37
45
|
* Route configuration interface.
|
|
38
46
|
* Routes specify content_module for surfaces and optionally route_module for lifecycle functions.
|
|
@@ -53,6 +61,7 @@ export interface Route {
|
|
|
53
61
|
* The module should export a named export `route` containing:
|
|
54
62
|
* - beforeLoad?: Pre-navigation hook (authentication, validation, redirects)
|
|
55
63
|
* - loader?: Data preloading function
|
|
64
|
+
* - canvas?: Function that returns canvas data for rendering an editor
|
|
56
65
|
*/
|
|
57
66
|
route_module?: string;
|
|
58
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC;AAExD,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,KAAK;IACrB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC;AAExD,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,KAAK;IACrB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,KAAK;IACrB,SAAS,EAAE,MAAM,CAAE,MAAM,EAAE,QAAQ,CAAE,CAAC;IACtC,MAAM,EAAE,KAAK,EAAE,CAAC;CAChB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/boot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Minimal boot package for WordPress admin pages.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -36,21 +36,24 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@tanstack/history": "^1.133.28",
|
|
38
38
|
"@tanstack/react-router": "^1.120.5",
|
|
39
|
-
"@wordpress/admin-ui": "^1.
|
|
40
|
-
"@wordpress/commands": "^1.
|
|
41
|
-
"@wordpress/components": "^30.
|
|
42
|
-
"@wordpress/compose": "^7.
|
|
43
|
-
"@wordpress/core-data": "^7.
|
|
44
|
-
"@wordpress/data": "^10.
|
|
45
|
-
"@wordpress/
|
|
46
|
-
"@wordpress/
|
|
47
|
-
"@wordpress/
|
|
48
|
-
"@wordpress/
|
|
49
|
-
"@wordpress/
|
|
50
|
-
"@wordpress/
|
|
51
|
-
"@wordpress/
|
|
52
|
-
"@wordpress/
|
|
53
|
-
"@wordpress/
|
|
39
|
+
"@wordpress/admin-ui": "^1.3.0",
|
|
40
|
+
"@wordpress/commands": "^1.35.0",
|
|
41
|
+
"@wordpress/components": "^30.8.0",
|
|
42
|
+
"@wordpress/compose": "^7.35.0",
|
|
43
|
+
"@wordpress/core-data": "^7.35.0",
|
|
44
|
+
"@wordpress/data": "^10.35.0",
|
|
45
|
+
"@wordpress/editor": "^14.35.0",
|
|
46
|
+
"@wordpress/element": "^6.35.0",
|
|
47
|
+
"@wordpress/html-entities": "^4.35.0",
|
|
48
|
+
"@wordpress/i18n": "^6.8.0",
|
|
49
|
+
"@wordpress/icons": "^11.2.0",
|
|
50
|
+
"@wordpress/keyboard-shortcuts": "^5.35.0",
|
|
51
|
+
"@wordpress/keycodes": "^4.35.0",
|
|
52
|
+
"@wordpress/lazy-editor": "^1.1.0",
|
|
53
|
+
"@wordpress/primitives": "^4.35.0",
|
|
54
|
+
"@wordpress/private-apis": "^1.35.0",
|
|
55
|
+
"@wordpress/theme": "^0.2.0",
|
|
56
|
+
"@wordpress/url": "^4.35.0",
|
|
54
57
|
"clsx": "^2.1.1"
|
|
55
58
|
},
|
|
56
59
|
"peerDependencies": {
|
|
@@ -60,5 +63,5 @@
|
|
|
60
63
|
"publishConfig": {
|
|
61
64
|
"access": "public"
|
|
62
65
|
},
|
|
63
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "77aa1f194edceafe8ac2a1b9438bf84b557e76e3"
|
|
64
67
|
}
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { createRoot, StrictMode } from '@wordpress/element';
|
|
4
|
+
import { createRoot, StrictMode, type ComponentType } from '@wordpress/element';
|
|
5
5
|
import { dispatch, useSelect } from '@wordpress/data';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Internal dependencies
|
|
9
9
|
*/
|
|
10
10
|
import Router from './router';
|
|
11
|
+
import RootSinglePage from '../root/single-page';
|
|
11
12
|
import { store } from '../../store';
|
|
12
13
|
import type { MenuItem, Route } from '../../store/types';
|
|
13
14
|
|
|
14
|
-
function App() {
|
|
15
|
+
function App( { rootComponent }: { rootComponent?: ComponentType } ) {
|
|
15
16
|
const routes = useSelect( ( select ) => select( store ).getRoutes(), [] );
|
|
16
17
|
|
|
17
|
-
return <Router routes={ routes } />;
|
|
18
|
+
return <Router routes={ routes } rootComponent={ rootComponent } />;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export async function init( {
|
|
22
|
+
mountId,
|
|
21
23
|
menuItems,
|
|
22
24
|
routes,
|
|
23
25
|
}: {
|
|
26
|
+
mountId: string;
|
|
24
27
|
menuItems?: MenuItem[];
|
|
25
28
|
routes?: Route[];
|
|
26
29
|
} ) {
|
|
@@ -33,7 +36,7 @@ export async function init( {
|
|
|
33
36
|
} );
|
|
34
37
|
|
|
35
38
|
// Render the app
|
|
36
|
-
const rootElement = document.getElementById(
|
|
39
|
+
const rootElement = document.getElementById( mountId );
|
|
37
40
|
if ( rootElement ) {
|
|
38
41
|
const root = createRoot( rootElement );
|
|
39
42
|
root.render(
|
|
@@ -43,3 +46,26 @@ export async function init( {
|
|
|
43
46
|
);
|
|
44
47
|
}
|
|
45
48
|
}
|
|
49
|
+
|
|
50
|
+
export async function initSinglePage( {
|
|
51
|
+
mountId,
|
|
52
|
+
routes,
|
|
53
|
+
}: {
|
|
54
|
+
mountId: string;
|
|
55
|
+
routes?: Route[];
|
|
56
|
+
} ) {
|
|
57
|
+
( routes ?? [] ).forEach( ( route ) => {
|
|
58
|
+
dispatch( store ).registerRoute( route );
|
|
59
|
+
} );
|
|
60
|
+
|
|
61
|
+
// Render the app without sidebar
|
|
62
|
+
const rootElement = document.getElementById( mountId );
|
|
63
|
+
if ( rootElement ) {
|
|
64
|
+
const root = createRoot( rootElement );
|
|
65
|
+
root.render(
|
|
66
|
+
<StrictMode>
|
|
67
|
+
<App rootComponent={ RootSinglePage } />
|
|
68
|
+
</StrictMode>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
RouterProvider,
|
|
9
9
|
createBrowserHistory,
|
|
10
10
|
type AnyRoute,
|
|
11
|
+
redirect,
|
|
11
12
|
} from '@tanstack/react-router';
|
|
12
13
|
import { parseHref } from '@tanstack/history';
|
|
13
14
|
import type { ComponentType } from 'react';
|
|
@@ -88,8 +89,11 @@ async function createRouteFromDefinition(
|
|
|
88
89
|
|
|
89
90
|
// Load route module for lifecycle functions if specified
|
|
90
91
|
let routeConfig: {
|
|
91
|
-
beforeLoad?: (
|
|
92
|
+
beforeLoad?: (
|
|
93
|
+
context: RouteLoaderContext & { redirect: Function }
|
|
94
|
+
) => void | Promise< void >;
|
|
92
95
|
loader?: ( context: RouteLoaderContext ) => Promise< unknown >;
|
|
96
|
+
canvas?: ( context: RouteLoaderContext ) => Promise< any >;
|
|
93
97
|
} = {};
|
|
94
98
|
|
|
95
99
|
if ( route.route_module ) {
|
|
@@ -101,23 +105,35 @@ async function createRouteFromDefinition(
|
|
|
101
105
|
getParentRoute: () => parentRoute,
|
|
102
106
|
path: route.path,
|
|
103
107
|
beforeLoad: routeConfig.beforeLoad
|
|
104
|
-
?
|
|
105
|
-
|
|
108
|
+
? ( opts: any ) =>
|
|
109
|
+
routeConfig.beforeLoad!( {
|
|
106
110
|
params: opts.params || {},
|
|
107
111
|
search: opts.search || {},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
: undefined,
|
|
112
|
-
loader: routeConfig.loader
|
|
113
|
-
? async ( opts: any ) => {
|
|
114
|
-
const context: RouteLoaderContext = {
|
|
115
|
-
params: opts.params || {},
|
|
116
|
-
search: opts.search || {},
|
|
117
|
-
};
|
|
118
|
-
return await routeConfig.loader!( context );
|
|
119
|
-
}
|
|
112
|
+
redirect,
|
|
113
|
+
} )
|
|
120
114
|
: undefined,
|
|
115
|
+
loader: async ( opts: any ) => {
|
|
116
|
+
const context: RouteLoaderContext = {
|
|
117
|
+
params: opts.params || {},
|
|
118
|
+
search: opts.deps || {},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Call both loader and canvas functions if they exist
|
|
122
|
+
const [ loaderData, canvasData ] = await Promise.all( [
|
|
123
|
+
routeConfig.loader
|
|
124
|
+
? routeConfig.loader( context )
|
|
125
|
+
: Promise.resolve( undefined ),
|
|
126
|
+
routeConfig.canvas
|
|
127
|
+
? routeConfig.canvas( context )
|
|
128
|
+
: Promise.resolve( undefined ),
|
|
129
|
+
] );
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
...( loaderData as any ),
|
|
133
|
+
canvas: canvasData,
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
loaderDeps: ( opts: any ) => opts.search,
|
|
121
137
|
component: SurfacesModule,
|
|
122
138
|
} );
|
|
123
139
|
}
|
|
@@ -125,12 +141,16 @@ async function createRouteFromDefinition(
|
|
|
125
141
|
/**
|
|
126
142
|
* Creates a route tree from route definitions.
|
|
127
143
|
*
|
|
128
|
-
* @param routes
|
|
144
|
+
* @param routes Routes definition.
|
|
145
|
+
* @param rootComponent Root component to use for the router.
|
|
129
146
|
* @return Router tree.
|
|
130
147
|
*/
|
|
131
|
-
async function createRouteTree(
|
|
148
|
+
async function createRouteTree(
|
|
149
|
+
routes: Route[],
|
|
150
|
+
rootComponent: ComponentType = Root
|
|
151
|
+
) {
|
|
132
152
|
const rootRoute = createRootRoute( {
|
|
133
|
-
component:
|
|
153
|
+
component: rootComponent as any,
|
|
134
154
|
context: () => ( {} ),
|
|
135
155
|
} );
|
|
136
156
|
|
|
@@ -161,9 +181,13 @@ function createPathHistory() {
|
|
|
161
181
|
|
|
162
182
|
interface RouterProps {
|
|
163
183
|
routes: Route[];
|
|
184
|
+
rootComponent?: ComponentType;
|
|
164
185
|
}
|
|
165
186
|
|
|
166
|
-
export default function Router( {
|
|
187
|
+
export default function Router( {
|
|
188
|
+
routes,
|
|
189
|
+
rootComponent = Root,
|
|
190
|
+
}: RouterProps ) {
|
|
167
191
|
const [ router, setRouter ] = useState< any >( null );
|
|
168
192
|
|
|
169
193
|
useEffect( () => {
|
|
@@ -171,7 +195,7 @@ export default function Router( { routes }: RouterProps ) {
|
|
|
171
195
|
|
|
172
196
|
async function initializeRouter() {
|
|
173
197
|
const history = createPathHistory();
|
|
174
|
-
const routeTree = await createRouteTree( routes );
|
|
198
|
+
const routeTree = await createRouteTree( routes, rootComponent );
|
|
175
199
|
|
|
176
200
|
if ( ! cancelled ) {
|
|
177
201
|
const newRouter = createRouter( {
|
|
@@ -188,7 +212,7 @@ export default function Router( { routes }: RouterProps ) {
|
|
|
188
212
|
return () => {
|
|
189
213
|
cancelled = true;
|
|
190
214
|
};
|
|
191
|
-
}, [ routes ] );
|
|
215
|
+
}, [ routes, rootComponent ] );
|
|
192
216
|
|
|
193
217
|
if ( ! router ) {
|
|
194
218
|
return <div>Loading routes...</div>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
@use "@wordpress/base-styles/variables";
|
|
2
|
+
|
|
3
|
+
.boot-canvas-back-button {
|
|
4
|
+
position: absolute;
|
|
5
|
+
top: 0;
|
|
6
|
+
left: 0;
|
|
7
|
+
height: variables.$header-height;
|
|
8
|
+
width: variables.$header-height;
|
|
9
|
+
z-index: 100;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.boot-canvas-back-button__container {
|
|
13
|
+
position: relative;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.boot-canvas-back-button__link.components-button {
|
|
19
|
+
width: variables.$header-height;
|
|
20
|
+
height: variables.$header-height;
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
background: var(--wpds-color-bg-surface-neutral-weak);
|
|
25
|
+
text-decoration: none;
|
|
26
|
+
padding: 0;
|
|
27
|
+
border-radius: 0;
|
|
28
|
+
|
|
29
|
+
@media not (prefers-reduced-motion) {
|
|
30
|
+
transition: outline 0.1s ease-out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&:focus:not(:active) {
|
|
34
|
+
outline:
|
|
35
|
+
var(--wpds-border-width-focus) solid
|
|
36
|
+
var(--wpds-color-stroke-focus-brand);
|
|
37
|
+
outline-offset: calc(-1 * var(--wpds-border-width-focus));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.boot-canvas-back-button__icon {
|
|
42
|
+
position: absolute;
|
|
43
|
+
top: 0;
|
|
44
|
+
left: 0;
|
|
45
|
+
width: variables.$header-height;
|
|
46
|
+
height: variables.$header-height;
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
background-color: hsla(0, 0%, 80%);
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
|
|
53
|
+
svg {
|
|
54
|
+
fill: currentColor;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&.has-site-icon {
|
|
58
|
+
background-color: hsla(0, 0%, 100%, 0.6);
|
|
59
|
+
-webkit-backdrop-filter: saturate(180%) blur(15px);
|
|
60
|
+
backdrop-filter: saturate(180%) blur(15px);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
Icon,
|
|
7
|
+
__unstableMotion as motion,
|
|
8
|
+
} from '@wordpress/components';
|
|
9
|
+
import { arrowUpLeft } from '@wordpress/icons';
|
|
10
|
+
import { useReducedMotion } from '@wordpress/compose';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Internal dependencies
|
|
15
|
+
*/
|
|
16
|
+
import SiteIcon from '../site-icon';
|
|
17
|
+
import './back-button.scss';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Overlay arrow animation that appears on hover.
|
|
21
|
+
* Matches next-admin implementation with clip-path.
|
|
22
|
+
*/
|
|
23
|
+
const toggleHomeIconVariants = {
|
|
24
|
+
edit: {
|
|
25
|
+
opacity: 0,
|
|
26
|
+
scale: 0.2,
|
|
27
|
+
},
|
|
28
|
+
hover: {
|
|
29
|
+
opacity: 1,
|
|
30
|
+
scale: 1,
|
|
31
|
+
clipPath: 'inset( 22% round 2px )',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Back button component that appears in full-screen canvas mode.
|
|
37
|
+
* Matches next-admin's SiteIconBackButton design.
|
|
38
|
+
*
|
|
39
|
+
* @param {Object} props Component props
|
|
40
|
+
* @param {number} props.length Number of BackButton fills (from Slot)
|
|
41
|
+
* @return Back button with slide and hover animations
|
|
42
|
+
*/
|
|
43
|
+
export default function BootBackButton( { length }: { length: number } ) {
|
|
44
|
+
const disableMotion = useReducedMotion();
|
|
45
|
+
|
|
46
|
+
const handleBack = () => {
|
|
47
|
+
window.history.back();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Only render if this is the only back button
|
|
51
|
+
if ( length > 1 ) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const transition = {
|
|
56
|
+
duration: disableMotion ? 0 : 0.3,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<motion.div
|
|
61
|
+
className="boot-canvas-back-button"
|
|
62
|
+
animate="edit"
|
|
63
|
+
initial="edit"
|
|
64
|
+
whileHover="hover"
|
|
65
|
+
whileTap="tap"
|
|
66
|
+
transition={ transition }
|
|
67
|
+
>
|
|
68
|
+
<Button
|
|
69
|
+
className="boot-canvas-back-button__link"
|
|
70
|
+
onClick={ handleBack }
|
|
71
|
+
aria-label={ __( 'Go back' ) }
|
|
72
|
+
__next40pxDefaultSize
|
|
73
|
+
>
|
|
74
|
+
<SiteIcon />
|
|
75
|
+
</Button>
|
|
76
|
+
|
|
77
|
+
{ /* Overlay arrow that appears on hover */ }
|
|
78
|
+
<motion.div
|
|
79
|
+
className="boot-canvas-back-button__icon"
|
|
80
|
+
variants={ toggleHomeIconVariants }
|
|
81
|
+
>
|
|
82
|
+
<Icon icon={ arrowUpLeft } />
|
|
83
|
+
</motion.div>
|
|
84
|
+
</motion.div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useState, useEffect } from '@wordpress/element';
|
|
5
|
+
import { Spinner } from '@wordpress/components';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import type { CanvasData } from '../../store/types';
|
|
11
|
+
import BootBackButton from './back-button';
|
|
12
|
+
|
|
13
|
+
interface CanvasProps {
|
|
14
|
+
canvas: CanvasData;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Canvas component that dynamically loads and renders the lazy editor.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} props - Component props
|
|
21
|
+
* @param {Object} props.canvas - Canvas data containing postType and postId
|
|
22
|
+
* @return Canvas surface with editor
|
|
23
|
+
*/
|
|
24
|
+
export default function Canvas( { canvas }: CanvasProps ) {
|
|
25
|
+
const [ Editor, setEditor ] = useState< any >( null );
|
|
26
|
+
|
|
27
|
+
useEffect( () => {
|
|
28
|
+
// Dynamically import the lazy-editor module
|
|
29
|
+
import( '@wordpress/lazy-editor' )
|
|
30
|
+
.then( ( module ) => {
|
|
31
|
+
setEditor( () => module.Editor );
|
|
32
|
+
} )
|
|
33
|
+
.catch( ( error ) => {
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.error( 'Failed to load lazy editor:', error );
|
|
36
|
+
} );
|
|
37
|
+
}, [] );
|
|
38
|
+
|
|
39
|
+
// Show spinner while loading the editor module
|
|
40
|
+
if ( ! Editor ) {
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
style={ {
|
|
44
|
+
display: 'flex',
|
|
45
|
+
justifyContent: 'center',
|
|
46
|
+
alignItems: 'center',
|
|
47
|
+
height: '100%',
|
|
48
|
+
padding: '2rem',
|
|
49
|
+
} }
|
|
50
|
+
>
|
|
51
|
+
<Spinner />
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Render back button in full-screen mode (when not preview)
|
|
57
|
+
// Uses render prop pattern to receive fillProps from Slot
|
|
58
|
+
const backButton = ! canvas.isPreview
|
|
59
|
+
? ( { length }: { length: number } ) => (
|
|
60
|
+
<BootBackButton length={ length } />
|
|
61
|
+
)
|
|
62
|
+
: undefined;
|
|
63
|
+
|
|
64
|
+
// Render the editor with canvas data
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
style={ { height: '100%' } }
|
|
68
|
+
// @ts-expect-error inert untyped properly.
|
|
69
|
+
inert={ canvas.isPreview ? 'true' : undefined }
|
|
70
|
+
>
|
|
71
|
+
<Editor
|
|
72
|
+
postType={ canvas.postType }
|
|
73
|
+
postId={ canvas.postId }
|
|
74
|
+
settings={ { isPreviewMode: canvas.isPreview } }
|
|
75
|
+
backButton={ backButton }
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|