@wordpress/boot 0.1.1-next.2f1c7c01b.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/LICENSE.md +788 -0
- package/build-module/components/app/index.js +32 -0
- package/build-module/components/app/index.js.map +7 -0
- package/build-module/components/app/router.js +119 -0
- package/build-module/components/app/router.js.map +7 -0
- package/build-module/components/navigation/drilldown-item/index.js +49 -0
- package/build-module/components/navigation/drilldown-item/index.js.map +7 -0
- package/build-module/components/navigation/dropdown-item/index.js +162 -0
- package/build-module/components/navigation/dropdown-item/index.js.map +7 -0
- package/build-module/components/navigation/index.js +101 -0
- package/build-module/components/navigation/index.js.map +7 -0
- package/build-module/components/navigation/items.js +60 -0
- package/build-module/components/navigation/items.js.map +7 -0
- package/build-module/components/navigation/navigation-item/index.js +180 -0
- package/build-module/components/navigation/navigation-item/index.js.map +7 -0
- package/build-module/components/navigation/navigation-screen/index.js +196 -0
- package/build-module/components/navigation/navigation-screen/index.js.map +7 -0
- package/build-module/components/navigation/path-matching.js +78 -0
- package/build-module/components/navigation/path-matching.js.map +7 -0
- package/build-module/components/navigation/router-link-item.js +14 -0
- package/build-module/components/navigation/router-link-item.js.map +7 -0
- package/build-module/components/navigation/use-sidebar-parent.js +52 -0
- package/build-module/components/navigation/use-sidebar-parent.js.map +7 -0
- package/build-module/components/root/index.js +115 -0
- package/build-module/components/root/index.js.map +7 -0
- package/build-module/components/sidebar/index.js +78 -0
- package/build-module/components/sidebar/index.js.map +7 -0
- package/build-module/components/site-hub/index.js +153 -0
- package/build-module/components/site-hub/index.js.map +7 -0
- package/build-module/components/site-icon/index.js +115 -0
- package/build-module/components/site-icon/index.js.map +7 -0
- package/build-module/components/site-icon-link/index.js +101 -0
- package/build-module/components/site-icon-link/index.js.map +7 -0
- package/build-module/index.js +622 -0
- package/build-module/index.js.map +7 -0
- package/build-module/lock-unlock.js +11 -0
- package/build-module/lock-unlock.js.map +7 -0
- package/build-module/store/actions.js +19 -0
- package/build-module/store/actions.js.map +7 -0
- package/build-module/store/index.js +17 -0
- package/build-module/store/index.js.map +7 -0
- package/build-module/store/reducer.js +27 -0
- package/build-module/store/reducer.js.map +7 -0
- package/build-module/store/selectors.js +12 -0
- package/build-module/store/selectors.js.map +7 -0
- package/build-module/store/types.js +1 -0
- package/build-module/store/types.js.map +7 -0
- package/build-style/style-rtl.css +612 -0
- package/build-style/style.css +612 -0
- package/build-types/components/app/index.d.ts +6 -0
- package/build-types/components/app/index.d.ts.map +1 -0
- package/build-types/components/app/router.d.ts +7 -0
- package/build-types/components/app/router.d.ts.map +1 -0
- package/build-types/components/navigation/drilldown-item/index.d.ts +34 -0
- package/build-types/components/navigation/drilldown-item/index.d.ts.map +1 -0
- package/build-types/components/navigation/dropdown-item/index.d.ts +36 -0
- package/build-types/components/navigation/dropdown-item/index.d.ts.map +1 -0
- package/build-types/components/navigation/index.d.ts +3 -0
- package/build-types/components/navigation/index.d.ts.map +1 -0
- package/build-types/components/navigation/items.d.ts +16 -0
- package/build-types/components/navigation/items.d.ts.map +1 -0
- package/build-types/components/navigation/navigation-item/index.d.ts +28 -0
- package/build-types/components/navigation/navigation-item/index.d.ts.map +1 -0
- package/build-types/components/navigation/navigation-screen/index.d.ts +24 -0
- package/build-types/components/navigation/navigation-screen/index.d.ts.map +1 -0
- package/build-types/components/navigation/path-matching.d.ts +30 -0
- package/build-types/components/navigation/path-matching.d.ts.map +1 -0
- package/build-types/components/navigation/router-link-item.d.ts +5 -0
- package/build-types/components/navigation/router-link-item.d.ts.map +1 -0
- package/build-types/components/navigation/use-sidebar-parent.d.ts +12 -0
- package/build-types/components/navigation/use-sidebar-parent.d.ts.map +1 -0
- package/build-types/components/root/index.d.ts +3 -0
- package/build-types/components/root/index.d.ts.map +1 -0
- package/build-types/components/sidebar/index.d.ts +3 -0
- package/build-types/components/sidebar/index.d.ts.map +1 -0
- package/build-types/components/site-hub/index.d.ts +4 -0
- package/build-types/components/site-hub/index.d.ts.map +1 -0
- package/build-types/components/site-icon/index.d.ts +9 -0
- package/build-types/components/site-icon/index.d.ts.map +1 -0
- package/build-types/components/site-icon-link/index.d.ts +8 -0
- package/build-types/components/site-icon-link/index.d.ts.map +1 -0
- package/build-types/index.d.ts +6 -0
- package/build-types/index.d.ts.map +1 -0
- package/build-types/lock-unlock.d.ts +2 -0
- package/build-types/lock-unlock.d.ts.map +1 -0
- package/build-types/store/actions.d.ts +15 -0
- package/build-types/store/actions.d.ts.map +1 -0
- package/build-types/store/index.d.ts +6 -0
- package/build-types/store/index.d.ts.map +1 -0
- package/build-types/store/reducer.d.ts +7 -0
- package/build-types/store/reducer.d.ts.map +1 -0
- package/build-types/store/selectors.d.ts +7 -0
- package/build-types/store/selectors.d.ts.map +1 -0
- package/build-types/store/types.d.ts +63 -0
- package/build-types/store/types.d.ts.map +1 -0
- package/package.json +64 -0
- package/src/components/app/index.tsx +45 -0
- package/src/components/app/router.tsx +198 -0
- package/src/components/navigation/drilldown-item/index.tsx +88 -0
- package/src/components/navigation/dropdown-item/index.tsx +134 -0
- package/src/components/navigation/dropdown-item/style.scss +23 -0
- package/src/components/navigation/index.tsx +126 -0
- package/src/components/navigation/items.tsx +93 -0
- package/src/components/navigation/navigation-item/index.tsx +88 -0
- package/src/components/navigation/navigation-item/style.scss +52 -0
- package/src/components/navigation/navigation-screen/index.tsx +147 -0
- package/src/components/navigation/navigation-screen/style.scss +34 -0
- package/src/components/navigation/path-matching.ts +149 -0
- package/src/components/navigation/router-link-item.tsx +22 -0
- package/src/components/navigation/use-sidebar-parent.ts +77 -0
- package/src/components/root/index.tsx +42 -0
- package/src/components/root/style.scss +41 -0
- package/src/components/sidebar/index.tsx +17 -0
- package/src/components/sidebar/style.scss +15 -0
- package/src/components/site-hub/index.tsx +67 -0
- package/src/components/site-hub/style.scss +54 -0
- package/src/components/site-icon/index.tsx +60 -0
- package/src/components/site-icon/style.scss +19 -0
- package/src/components/site-icon-link/index.tsx +43 -0
- package/src/components/site-icon-link/style.scss +24 -0
- package/src/index.tsx +5 -0
- package/src/lock-unlock.ts +9 -0
- package/src/store/actions.ts +23 -0
- package/src/store/index.ts +23 -0
- package/src/store/reducer.ts +31 -0
- package/src/store/selectors.ts +12 -0
- package/src/store/types.ts +70 -0
- package/src/style.scss +2 -0
- package/tsconfig.json +23 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
5
|
+
import {
|
|
6
|
+
ExternalLink,
|
|
7
|
+
Button,
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
__experimentalHStack as HStack,
|
|
10
|
+
} from '@wordpress/components';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
13
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
14
|
+
import { search } from '@wordpress/icons';
|
|
15
|
+
import { displayShortcut } from '@wordpress/keycodes';
|
|
16
|
+
// @ts-expect-error Commands is not typed properly.
|
|
17
|
+
import { store as commandsStore } from '@wordpress/commands';
|
|
18
|
+
import { filterURLForDisplay } from '@wordpress/url';
|
|
19
|
+
import type { UnstableBase } from '@wordpress/core-data';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Internal dependencies
|
|
23
|
+
*/
|
|
24
|
+
import SiteIconLink from '../site-icon-link';
|
|
25
|
+
import './style.scss';
|
|
26
|
+
|
|
27
|
+
function SiteHub() {
|
|
28
|
+
const { homeUrl, siteTitle } = useSelect( ( select ) => {
|
|
29
|
+
const { getEntityRecord } = select( coreStore );
|
|
30
|
+
const _base = getEntityRecord< UnstableBase >(
|
|
31
|
+
'root',
|
|
32
|
+
'__unstableBase'
|
|
33
|
+
);
|
|
34
|
+
return {
|
|
35
|
+
homeUrl: _base?.home,
|
|
36
|
+
siteTitle:
|
|
37
|
+
! _base?.name && !! _base?.url
|
|
38
|
+
? filterURLForDisplay( _base?.url )
|
|
39
|
+
: _base?.name,
|
|
40
|
+
};
|
|
41
|
+
}, [] );
|
|
42
|
+
const { open: openCommandCenter } = useDispatch( commandsStore );
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div className="boot-site-hub">
|
|
46
|
+
<SiteIconLink to="/" aria-label={ __( 'Go to the Dashboard' ) } />
|
|
47
|
+
<ExternalLink
|
|
48
|
+
href={ homeUrl ?? '/' }
|
|
49
|
+
className="boot-site-hub__title"
|
|
50
|
+
>
|
|
51
|
+
{ siteTitle && decodeEntities( siteTitle ) }
|
|
52
|
+
</ExternalLink>
|
|
53
|
+
<HStack className="boot-site-hub__actions">
|
|
54
|
+
<Button
|
|
55
|
+
variant="tertiary"
|
|
56
|
+
icon={ search }
|
|
57
|
+
onClick={ () => openCommandCenter() }
|
|
58
|
+
size="compact"
|
|
59
|
+
label={ __( 'Open command palette' ) }
|
|
60
|
+
shortcut={ displayShortcut.primary( 'k' ) }
|
|
61
|
+
/>
|
|
62
|
+
</HStack>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default SiteHub;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
@use "@wordpress/base-styles/variables";
|
|
2
|
+
|
|
3
|
+
.boot-site-hub {
|
|
4
|
+
position: sticky;
|
|
5
|
+
top: 0;
|
|
6
|
+
background-color: var(--wpds-color-bg-surface-neutral-weak, #f0f0f0);
|
|
7
|
+
z-index: 1;
|
|
8
|
+
display: grid;
|
|
9
|
+
grid-template-columns: 60px 1fr auto;
|
|
10
|
+
align-items: center;
|
|
11
|
+
padding-right: variables.$grid-unit-20;
|
|
12
|
+
flex-shrink: 0; // Prevent flex parent from shrinking this element.
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.boot-site-hub__actions {
|
|
16
|
+
flex-shrink: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.boot-site-hub__title {
|
|
20
|
+
color: var(--wpds-color-fg-content-neutral, #1e1e1e);
|
|
21
|
+
font-size: variables.$font-size-medium;
|
|
22
|
+
font-weight: variables.$font-weight-medium;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
text-overflow: ellipsis;
|
|
25
|
+
white-space: nowrap;
|
|
26
|
+
text-decoration: none;
|
|
27
|
+
|
|
28
|
+
.components-external-link__contents {
|
|
29
|
+
text-decoration: none;
|
|
30
|
+
margin-inline-start: variables.$grid-unit-05;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Show icon on hover
|
|
34
|
+
.components-external-link__icon {
|
|
35
|
+
opacity: 0;
|
|
36
|
+
transition: opacity 0.1s ease-out;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&:hover .components-external-link__icon {
|
|
40
|
+
opacity: 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Focus styles
|
|
44
|
+
@media not (prefers-reduced-motion) {
|
|
45
|
+
transition: outline 0.1s ease-out;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&:focus:not(:active) {
|
|
49
|
+
outline:
|
|
50
|
+
var(--wpds-border-width-focus, 2px) solid
|
|
51
|
+
var(--wpds-color-stroke-focus-brand, #0073aa);
|
|
52
|
+
outline-offset: calc(-1 * var(--wpds-border-width-focus, 2px));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
import { Icon, wordpress } from '@wordpress/icons';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
import { store as coreDataStore } from '@wordpress/core-data';
|
|
13
|
+
import type { UnstableBase } from '@wordpress/core-data';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Internal dependencies
|
|
17
|
+
*/
|
|
18
|
+
import './style.scss';
|
|
19
|
+
|
|
20
|
+
function SiteIcon( { className }: { className?: string } ) {
|
|
21
|
+
const { isRequestingSite, siteIconUrl } = useSelect( ( select ) => {
|
|
22
|
+
const { getEntityRecord } = select( coreDataStore );
|
|
23
|
+
const siteData = getEntityRecord< UnstableBase >(
|
|
24
|
+
'root',
|
|
25
|
+
'__unstableBase',
|
|
26
|
+
undefined
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
isRequestingSite: ! siteData,
|
|
31
|
+
siteIconUrl: siteData?.site_icon_url,
|
|
32
|
+
};
|
|
33
|
+
}, [] );
|
|
34
|
+
|
|
35
|
+
let icon = null;
|
|
36
|
+
|
|
37
|
+
if ( isRequestingSite && ! siteIconUrl ) {
|
|
38
|
+
icon = <div className="boot-site-icon__image" />;
|
|
39
|
+
} else {
|
|
40
|
+
icon = siteIconUrl ? (
|
|
41
|
+
<img
|
|
42
|
+
className="boot-site-icon__image"
|
|
43
|
+
alt={ __( 'Site Icon' ) }
|
|
44
|
+
src={ siteIconUrl }
|
|
45
|
+
/>
|
|
46
|
+
) : (
|
|
47
|
+
<Icon
|
|
48
|
+
className="boot-site-icon__icon"
|
|
49
|
+
icon={ wordpress }
|
|
50
|
+
size={ 48 }
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className={ clsx( className, 'boot-site-icon' ) }>{ icon }</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default SiteIcon;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@use "@wordpress/base-styles/variables";
|
|
2
|
+
|
|
3
|
+
.boot-site-icon {
|
|
4
|
+
display: flex;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.boot-site-icon__icon {
|
|
8
|
+
width: variables.$grid-unit-40;
|
|
9
|
+
height: variables.$grid-unit-40;
|
|
10
|
+
color: var(--wpds-color-fg-content-neutral, #1e1e1e);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.boot-site-icon__image {
|
|
14
|
+
width: variables.$grid-unit-40;
|
|
15
|
+
height: variables.$grid-unit-40;
|
|
16
|
+
object-fit: cover;
|
|
17
|
+
aspect-ratio: 1 / 1;
|
|
18
|
+
border-radius: var(--wpds-border-radius-medium, 4px);
|
|
19
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { Link, useCanGoBack, useRouter } from '@tanstack/react-router';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import SiteIcon from '../site-icon';
|
|
10
|
+
import './style.scss';
|
|
11
|
+
|
|
12
|
+
function SiteIconLink( {
|
|
13
|
+
to,
|
|
14
|
+
isBackButton,
|
|
15
|
+
...props
|
|
16
|
+
}: {
|
|
17
|
+
to: string;
|
|
18
|
+
'aria-label': string;
|
|
19
|
+
isBackButton?: boolean;
|
|
20
|
+
} ) {
|
|
21
|
+
const router = useRouter();
|
|
22
|
+
const canGoBack = useCanGoBack();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Link
|
|
26
|
+
to={ to }
|
|
27
|
+
aria-label={ props[ 'aria-label' ] }
|
|
28
|
+
className="boot-site-icon-link"
|
|
29
|
+
onClick={ ( event ) => {
|
|
30
|
+
// If possible, restore the previous page with
|
|
31
|
+
// filters etc.
|
|
32
|
+
if ( canGoBack && isBackButton ) {
|
|
33
|
+
event.preventDefault();
|
|
34
|
+
router.history.back();
|
|
35
|
+
}
|
|
36
|
+
} }
|
|
37
|
+
>
|
|
38
|
+
<SiteIcon />
|
|
39
|
+
</Link>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default SiteIconLink;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@use "@wordpress/base-styles/variables";
|
|
2
|
+
|
|
3
|
+
$header-height: variables.$header-height;
|
|
4
|
+
|
|
5
|
+
.boot-site-icon-link {
|
|
6
|
+
width: $header-height;
|
|
7
|
+
height: $header-height;
|
|
8
|
+
display: inline-flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
background: var(--wpds-color-bg-surface-neutral-weak, #f0f0f0);
|
|
12
|
+
text-decoration: none;
|
|
13
|
+
|
|
14
|
+
@media not (prefers-reduced-motion) {
|
|
15
|
+
transition: outline 0.1s ease-out;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&:focus:not(:active) {
|
|
19
|
+
outline:
|
|
20
|
+
var(--wpds-border-width-focus, 2px) solid
|
|
21
|
+
var(--wpds-color-stroke-focus-brand, #0073aa);
|
|
22
|
+
outline-offset: calc(-1 * var(--wpds-border-width-focus, 2px));
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';
|
|
5
|
+
export const { lock, unlock } =
|
|
6
|
+
__dangerousOptInToUnstableAPIsOnlyForCoreModules(
|
|
7
|
+
'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
|
|
8
|
+
'@wordpress/boot'
|
|
9
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { MenuItem, Route } from './types';
|
|
5
|
+
|
|
6
|
+
export function registerMenuItem( id: string, menuItem: MenuItem ) {
|
|
7
|
+
return {
|
|
8
|
+
type: 'REGISTER_MENU_ITEM' as const,
|
|
9
|
+
id,
|
|
10
|
+
menuItem,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function registerRoute( route: Route ) {
|
|
15
|
+
return {
|
|
16
|
+
type: 'REGISTER_ROUTE' as const,
|
|
17
|
+
route,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type Action =
|
|
22
|
+
| ReturnType< typeof registerMenuItem >
|
|
23
|
+
| ReturnType< typeof registerRoute >;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { createReduxStore, register } from '@wordpress/data';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { reducer } from './reducer';
|
|
10
|
+
import * as actions from './actions';
|
|
11
|
+
import * as selectors from './selectors';
|
|
12
|
+
|
|
13
|
+
const STORE_NAME = 'wordpress/boot';
|
|
14
|
+
|
|
15
|
+
export const store = createReduxStore( STORE_NAME, {
|
|
16
|
+
reducer,
|
|
17
|
+
actions,
|
|
18
|
+
selectors,
|
|
19
|
+
} );
|
|
20
|
+
|
|
21
|
+
register( store );
|
|
22
|
+
|
|
23
|
+
export { STORE_NAME };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { Action } from './actions';
|
|
5
|
+
import type { State } from './types';
|
|
6
|
+
|
|
7
|
+
const initialState: State = {
|
|
8
|
+
menuItems: {},
|
|
9
|
+
routes: [],
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function reducer( state: State = initialState, action: Action ): State {
|
|
13
|
+
switch ( action.type ) {
|
|
14
|
+
case 'REGISTER_MENU_ITEM':
|
|
15
|
+
return {
|
|
16
|
+
...state,
|
|
17
|
+
menuItems: {
|
|
18
|
+
...state.menuItems,
|
|
19
|
+
[ action.id ]: action.menuItem,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
case 'REGISTER_ROUTE':
|
|
24
|
+
return {
|
|
25
|
+
...state,
|
|
26
|
+
routes: [ ...state.routes, action.route ],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return state;
|
|
31
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { ReactNode, ComponentType } from 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Icon type supporting multiple formats:
|
|
8
|
+
* - Dashicon strings (e.g., "dashicons-admin-generic")
|
|
9
|
+
* - JSX elements
|
|
10
|
+
* - SVG icons from @wordpress/icons
|
|
11
|
+
* - Data URLs for images
|
|
12
|
+
*/
|
|
13
|
+
export type IconType = string | JSX.Element | ReactNode;
|
|
14
|
+
|
|
15
|
+
export interface MenuItem {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
to: string;
|
|
19
|
+
icon?: IconType;
|
|
20
|
+
parent?: string;
|
|
21
|
+
parent_type?: 'drilldown' | 'dropdown';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Route surfaces exported from content_module.
|
|
26
|
+
* Stage is required, inspector is optional.
|
|
27
|
+
*/
|
|
28
|
+
export interface RouteSurfaces {
|
|
29
|
+
stage?: ComponentType;
|
|
30
|
+
inspector?: ComponentType;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Route loader context containing params and search.
|
|
35
|
+
*/
|
|
36
|
+
export interface RouteLoaderContext {
|
|
37
|
+
params: Record< string, string >;
|
|
38
|
+
search: Record< string, unknown >;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Route configuration interface.
|
|
43
|
+
* Routes specify content_module for surfaces and optionally route_module for lifecycle functions.
|
|
44
|
+
*/
|
|
45
|
+
export interface Route {
|
|
46
|
+
/**
|
|
47
|
+
* Route path (e.g., "/post-edit/$postId")
|
|
48
|
+
*/
|
|
49
|
+
path: string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Module path for lazy loading the route's surfaces (stage, inspector).
|
|
53
|
+
* The module must export: RouteSurfaces (stage and/or inspector components)
|
|
54
|
+
* This enables code splitting for better performance.
|
|
55
|
+
*/
|
|
56
|
+
content_module?: string;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Module path for route lifecycle functions.
|
|
60
|
+
* The module should export a named export `route` containing:
|
|
61
|
+
* - beforeLoad?: Pre-navigation hook (authentication, validation, redirects)
|
|
62
|
+
* - loader?: Data preloading function
|
|
63
|
+
*/
|
|
64
|
+
route_module?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface State {
|
|
68
|
+
menuItems: Record< string, MenuItem >;
|
|
69
|
+
routes: Route[];
|
|
70
|
+
}
|
package/src/style.scss
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig.json",
|
|
3
|
+
"extends": "../../tsconfig.base.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"checkJs": false
|
|
6
|
+
},
|
|
7
|
+
"references": [
|
|
8
|
+
{ "path": "../admin-ui" },
|
|
9
|
+
{ "path": "../components" },
|
|
10
|
+
{ "path": "../compose" },
|
|
11
|
+
{ "path": "../core-data" },
|
|
12
|
+
{ "path": "../data" },
|
|
13
|
+
{ "path": "../element" },
|
|
14
|
+
{ "path": "../html-entities" },
|
|
15
|
+
{ "path": "../i18n" },
|
|
16
|
+
{ "path": "../icons" },
|
|
17
|
+
{ "path": "../keycodes" },
|
|
18
|
+
{ "path": "../primitives" },
|
|
19
|
+
{ "path": "../private-apis" },
|
|
20
|
+
{ "path": "../theme" },
|
|
21
|
+
{ "path": "../url" }
|
|
22
|
+
]
|
|
23
|
+
}
|