@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.
Files changed (56) hide show
  1. package/build-module/components/app/index.js +22 -4
  2. package/build-module/components/app/index.js.map +2 -2
  3. package/build-module/components/app/router.js +26 -16
  4. package/build-module/components/app/router.js.map +2 -2
  5. package/build-module/components/canvas/back-button.js +176 -0
  6. package/build-module/components/canvas/back-button.js.map +7 -0
  7. package/build-module/components/canvas/index.js +51 -0
  8. package/build-module/components/canvas/index.js.map +7 -0
  9. package/build-module/components/root/index.js +68 -14
  10. package/build-module/components/root/index.js.map +2 -2
  11. package/build-module/components/root/single-page.js +167 -0
  12. package/build-module/components/root/single-page.js.map +7 -0
  13. package/build-module/components/save-panel/index.js +36 -0
  14. package/build-module/components/save-panel/index.js.map +7 -0
  15. package/build-module/components/save-panel/use-save-shortcut.js +55 -0
  16. package/build-module/components/save-panel/use-save-shortcut.js.map +7 -0
  17. package/build-module/index.js +213 -416
  18. package/build-module/index.js.map +2 -2
  19. package/build-style/style-rtl.css +209 -413
  20. package/build-style/style.css +209 -413
  21. package/build-types/components/app/index.d.ts +6 -1
  22. package/build-types/components/app/index.d.ts.map +1 -1
  23. package/build-types/components/app/router.d.ts +3 -1
  24. package/build-types/components/app/router.d.ts.map +1 -1
  25. package/build-types/components/canvas/back-button.d.ts +13 -0
  26. package/build-types/components/canvas/back-button.d.ts.map +1 -0
  27. package/build-types/components/canvas/index.d.ts +17 -0
  28. package/build-types/components/canvas/index.d.ts.map +1 -0
  29. package/build-types/components/navigation/path-matching.d.ts.map +1 -1
  30. package/build-types/components/root/index.d.ts.map +1 -1
  31. package/build-types/components/root/single-page.d.ts +7 -0
  32. package/build-types/components/root/single-page.d.ts.map +1 -0
  33. package/build-types/components/save-panel/index.d.ts +2 -0
  34. package/build-types/components/save-panel/index.d.ts.map +1 -0
  35. package/build-types/components/save-panel/use-save-shortcut.d.ts +10 -0
  36. package/build-types/components/save-panel/use-save-shortcut.d.ts.map +1 -0
  37. package/build-types/index.d.ts +1 -1
  38. package/build-types/index.d.ts.map +1 -1
  39. package/build-types/store/types.d.ts +9 -0
  40. package/build-types/store/types.d.ts.map +1 -1
  41. package/package.json +20 -17
  42. package/src/components/app/index.tsx +30 -4
  43. package/src/components/app/router.tsx +45 -21
  44. package/src/components/canvas/back-button.scss +62 -0
  45. package/src/components/canvas/back-button.tsx +86 -0
  46. package/src/components/canvas/index.tsx +79 -0
  47. package/src/components/root/index.tsx +30 -6
  48. package/src/components/root/single-page.tsx +64 -0
  49. package/src/components/root/style.scss +36 -1
  50. package/src/components/save-panel/index.tsx +35 -0
  51. package/src/components/save-panel/use-save-shortcut.ts +67 -0
  52. package/src/index.tsx +1 -1
  53. package/src/store/types.ts +10 -0
  54. package/src/style.scss +43 -0
  55. package/tsconfig.json +2 -0
  56. 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":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAQzD,wBAAsB,IAAI,CAAE,EAC3B,SAAS,EACT,MAAM,GACN,EAAE;IACF,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB,iBAmBA"}
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":"AAyBA,OAAO,KAAK,EAAE,KAAK,EAAsB,MAAM,mBAAmB,CAAC;AAwInE,UAAU,WAAW;IACpB,MAAM,EAAE,KAAK,EAAE,CAAC;CAChB;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAAE,EAAE,MAAM,EAAE,EAAE,WAAW,+BAgCtD"}
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,gBAClB,MAAM,aACR,QAAQ,EAAE,KACnB,QAAQ,GAAG,IAyBb,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,OAC3B,MAAM,GAAG,SAAS,aACX,QAAQ,EAAE,KACnB,MAAM,GAAG,SA0BX,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,OAC1B,MAAM,GAAG,SAAS,aACX,QAAQ,EAAE,KACnB,MAAM,GAAG,SAsBX,CAAC"}
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":"AAiBA,OAAO,cAAc,CAAC;AAItB,MAAM,CAAC,OAAO,UAAU,IAAI,gCAoB3B"}
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,2 @@
1
+ export default function SavePanel(): false | import("react").JSX.Element;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -2,5 +2,5 @@
2
2
  * Internal dependencies
3
3
  */
4
4
  import './style.scss';
5
- export { init } from './components/app';
5
+ export { init, initSinglePage } from './components/app';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -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;;;;;OAKG;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"}
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.1.1-next.2f1c7c01b.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.2.1-next.2f1c7c01b.0",
40
- "@wordpress/commands": "^1.34.1-next.2f1c7c01b.0",
41
- "@wordpress/components": "^30.7.2-next.2f1c7c01b.0",
42
- "@wordpress/compose": "^7.34.1-next.2f1c7c01b.0",
43
- "@wordpress/core-data": "^7.34.1-next.2f1c7c01b.0",
44
- "@wordpress/data": "^10.34.1-next.2f1c7c01b.0",
45
- "@wordpress/element": "^6.34.1-next.2f1c7c01b.0",
46
- "@wordpress/html-entities": "^4.34.1-next.2f1c7c01b.0",
47
- "@wordpress/i18n": "^6.7.1-next.2f1c7c01b.0",
48
- "@wordpress/icons": "^11.1.1-next.2f1c7c01b.0",
49
- "@wordpress/keycodes": "^4.34.1-next.2f1c7c01b.0",
50
- "@wordpress/primitives": "^4.34.1-next.2f1c7c01b.0",
51
- "@wordpress/private-apis": "^1.34.1-next.2f1c7c01b.0",
52
- "@wordpress/theme": "^0.1.1-next.2f1c7c01b.0",
53
- "@wordpress/url": "^4.34.1-next.2f1c7c01b.0",
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": "c6ddcdf455bc02567a2c9e03de6862a2061b85e8"
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( 'gutenberg-boot-app' );
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?: ( context: RouteLoaderContext ) => void | Promise< void >;
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
- ? async ( opts: any ) => {
105
- const context: RouteLoaderContext = {
108
+ ? ( opts: any ) =>
109
+ routeConfig.beforeLoad!( {
106
110
  params: opts.params || {},
107
111
  search: opts.search || {},
108
- };
109
- await routeConfig.beforeLoad!( context );
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 Routes definition.
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( routes: Route[] ) {
148
+ async function createRouteTree(
149
+ routes: Route[],
150
+ rootComponent: ComponentType = Root
151
+ ) {
132
152
  const rootRoute = createRootRoute( {
133
- component: Root,
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( { routes }: RouterProps ) {
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
+ }