Allow custom icons and additional links in left nav
This commit is contained in:
parent
a82f27100e
commit
04098bf96d
@ -62,6 +62,7 @@ collections: # A list of collections the CMS should be able to edit
|
||||
|
||||
- name: 'settings'
|
||||
label: 'Settings'
|
||||
icon: 'settings'
|
||||
delete: false # Prevent users from deleting documents in this collection
|
||||
editor:
|
||||
preview: false
|
||||
|
@ -237,6 +237,7 @@
|
||||
);
|
||||
}
|
||||
});
|
||||
CMS.registerAdditionalLink('Example.com', 'https://example.com/', 'new-tab');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
// Core
|
||||
import { NetlifyCmsCore as CMS } from 'netlify-cms-core';
|
||||
// Backends
|
||||
@ -29,6 +30,7 @@ import NetlifyCmsWidgetColorString from 'netlify-cms-widget-colorstring';
|
||||
import image from 'netlify-cms-editor-component-image';
|
||||
// Locales
|
||||
import * as locales from 'netlify-cms-locales';
|
||||
import { images, Icon } from 'netlify-cms-ui-default';
|
||||
|
||||
// Register all the things
|
||||
CMS.registerBackend('git-gateway', GitGatewayBackend);
|
||||
@ -66,3 +68,7 @@ CMS.registerEditorComponent({
|
||||
Object.keys(locales).forEach(locale => {
|
||||
CMS.registerLocale(locale, locales[locale]);
|
||||
});
|
||||
|
||||
Object.keys(images).forEach(iconName => {
|
||||
CMS.registerIcon(iconName, <Icon type={iconName} />);
|
||||
});
|
||||
|
7
packages/netlify-cms-core/index.d.ts
vendored
7
packages/netlify-cms-core/index.d.ts
vendored
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
declare module 'netlify-cms-core' {
|
||||
import type { ComponentType } from 'react';
|
||||
import type { ComponentType, ReactNode } from 'react';
|
||||
import type { List, Map } from 'immutable';
|
||||
import type { Pluggable } from 'unified';
|
||||
|
||||
@ -578,7 +578,10 @@ declare module 'netlify-cms-core' {
|
||||
widgetName: string,
|
||||
serializer: CmsWidgetValueSerializer,
|
||||
) => void;
|
||||
resolveWidget: (name: string) => CmsWidget | undefined;
|
||||
registerIcon: (iconName: string, icon: ReactNode) => void;
|
||||
getIcon: (iconName: string) => ReactNode;
|
||||
registerAdditionalLink: (title: string, link: string, iconName?: string) => void;
|
||||
getAdditionalLinks: () => { title: string, link: string, iconName?: string }[];
|
||||
}
|
||||
|
||||
export const NetlifyCmsCore: CMS;
|
||||
|
@ -10,6 +10,7 @@ import { Icon, components, colors } from 'netlify-cms-ui-default';
|
||||
import { searchCollections } from '../../actions/collections';
|
||||
import CollectionSearch from './CollectionSearch';
|
||||
import NestedCollection from './NestedCollection';
|
||||
import { getAdditionalLinks, getIcon } from '../../lib/registry';
|
||||
|
||||
const styles = {
|
||||
sidebarNavLinkActive: css`
|
||||
@ -67,6 +68,26 @@ const SidebarNavLink = styled(NavLink)`
|
||||
`};
|
||||
`;
|
||||
|
||||
const AdditionalLink = styled.a`
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-left: 2px solid #fff;
|
||||
z-index: -1;
|
||||
|
||||
${Icon} {
|
||||
margin-right: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
${styles.sidebarNavLinkActive};
|
||||
}
|
||||
`;
|
||||
|
||||
export class Sidebar extends React.Component {
|
||||
static propTypes = {
|
||||
collections: ImmutablePropTypes.map.isRequired,
|
||||
@ -79,6 +100,14 @@ export class Sidebar extends React.Component {
|
||||
|
||||
renderLink = (collection, filterTerm) => {
|
||||
const collectionName = collection.get('name');
|
||||
const iconName = collection.get('icon');
|
||||
let icon = <Icon type="write" />;
|
||||
if (iconName) {
|
||||
const storedIcon = getIcon(iconName);
|
||||
if (storedIcon) {
|
||||
icon = storedIcon;
|
||||
}
|
||||
}
|
||||
if (collection.has('nested')) {
|
||||
return (
|
||||
<li key={collectionName}>
|
||||
@ -97,7 +126,60 @@ export class Sidebar extends React.Component {
|
||||
activeClassName="sidebar-active"
|
||||
data-testid={collectionName}
|
||||
>
|
||||
<Icon type="write" />
|
||||
{icon}
|
||||
{collection.get('label')}
|
||||
</SidebarNavLink>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
renderAdditionalLink = ({ title, url, iconName }) => {
|
||||
let icon = <Icon type="write" />;
|
||||
if (iconName) {
|
||||
const storedIcon = getIcon(iconName);
|
||||
if (storedIcon) {
|
||||
icon = storedIcon;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<li key={title}>
|
||||
<AdditionalLink href={url} target="_blank" rel="noopener">
|
||||
{icon}
|
||||
{title}
|
||||
</AdditionalLink>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
renderLink = (collection, filterTerm) => {
|
||||
const collectionName = collection.get('name');
|
||||
const iconName = collection.get('icon');
|
||||
let icon = <Icon type="write" />;
|
||||
if (iconName) {
|
||||
const storedIcon = getIcon(iconName);
|
||||
if (storedIcon) {
|
||||
icon = storedIcon;
|
||||
}
|
||||
}
|
||||
if (collection.has('nested')) {
|
||||
return (
|
||||
<li key={collectionName}>
|
||||
<NestedCollection
|
||||
collection={collection}
|
||||
filterTerm={filterTerm}
|
||||
data-testid={collectionName}
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<li key={collectionName}>
|
||||
<SidebarNavLink
|
||||
to={`/collections/${collectionName}`}
|
||||
activeClassName="sidebar-active"
|
||||
data-testid={collectionName}
|
||||
>
|
||||
{icon}
|
||||
{collection.get('label')}
|
||||
</SidebarNavLink>
|
||||
</li>
|
||||
@ -106,6 +188,7 @@ export class Sidebar extends React.Component {
|
||||
|
||||
render() {
|
||||
const { collections, collection, isSearchEnabled, searchTerm, t, filterTerm } = this.props;
|
||||
const additionalLinks = getAdditionalLinks();
|
||||
return (
|
||||
<SidebarContainer>
|
||||
<SidebarHeading>{t('collection.sidebar.collections')}</SidebarHeading>
|
||||
@ -122,6 +205,7 @@ export class Sidebar extends React.Component {
|
||||
.toList()
|
||||
.filter(collection => collection.get('hide') !== true)
|
||||
.map(collection => this.renderLink(collection, filterTerm))}
|
||||
{additionalLinks.map(this.renderAdditionalLink)}
|
||||
</SidebarNavList>
|
||||
</SidebarContainer>
|
||||
);
|
||||
|
@ -25,6 +25,8 @@ const registry = {
|
||||
templates: {},
|
||||
previewStyles: [],
|
||||
widgets: {},
|
||||
icons: {},
|
||||
additionalLinks: [],
|
||||
editorComponents: Map(),
|
||||
remarkPlugins: [],
|
||||
widgetValueSerializers: {},
|
||||
@ -58,6 +60,10 @@ export default {
|
||||
removeEventListener,
|
||||
getEventListeners,
|
||||
invokeEvent,
|
||||
registerIcon,
|
||||
getIcon,
|
||||
registerAdditionalLink,
|
||||
getAdditionalLinks
|
||||
};
|
||||
|
||||
/**
|
||||
@ -284,3 +290,23 @@ export function registerLocale(locale, phrases) {
|
||||
export function getLocale(locale) {
|
||||
return registry.locales[locale];
|
||||
}
|
||||
|
||||
/**
|
||||
* Icons
|
||||
*/
|
||||
export function registerIcon(name, icon) {
|
||||
registry.icons[name] = icon;
|
||||
}
|
||||
export function getIcon(name) {
|
||||
return registry.icons[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Icons
|
||||
*/
|
||||
export function registerAdditionalLink(title, url, iconName) {
|
||||
registry.additionalLinks.push({ title, url, iconName });
|
||||
}
|
||||
export function getAdditionalLinks() {
|
||||
return registry.additionalLinks;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import AuthenticationPage from './AuthenticationPage';
|
||||
import WidgetPreviewContainer from './WidgetPreviewContainer';
|
||||
import ObjectWidgetTopBar from './ObjectWidgetTopBar';
|
||||
import GoBackButton from './GoBackButton';
|
||||
import images from './Icon/images/_index';
|
||||
import {
|
||||
fonts,
|
||||
colorsRaw,
|
||||
@ -63,6 +64,7 @@ export const NetlifyCmsUiDefault = {
|
||||
zIndex,
|
||||
reactSelectStyles,
|
||||
GlobalStyles,
|
||||
images,
|
||||
};
|
||||
export {
|
||||
Dropdown,
|
||||
@ -97,4 +99,5 @@ export {
|
||||
reactSelectStyles,
|
||||
GlobalStyles,
|
||||
GoBackButton,
|
||||
images,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user