mirror of
https://github.com/flarum/core.git
synced 2025-08-05 07:57:46 +02:00
common: add Navigation component
This commit is contained in:
@@ -43,7 +43,7 @@ import SplitDropdown from './components/SplitDropdown';
|
|||||||
import RequestErrorModal from './components/RequestErrorModal';
|
import RequestErrorModal from './components/RequestErrorModal';
|
||||||
import FieldSet from './components/FieldSet';
|
import FieldSet from './components/FieldSet';
|
||||||
// import Select from './components/Select';
|
// import Select from './components/Select';
|
||||||
// import Navigation from './components/Navigation';
|
import Navigation from './components/Navigation';
|
||||||
import Alert from './components/Alert';
|
import Alert from './components/Alert';
|
||||||
import LinkButton from './components/LinkButton';
|
import LinkButton from './components/LinkButton';
|
||||||
import Checkbox from './components/Checkbox';
|
import Checkbox from './components/Checkbox';
|
||||||
@@ -107,7 +107,7 @@ export default {
|
|||||||
'components/RequestErrorModal': RequestErrorModal,
|
'components/RequestErrorModal': RequestErrorModal,
|
||||||
'components/FieldSet': FieldSet,
|
'components/FieldSet': FieldSet,
|
||||||
// 'components/Select': Select,
|
// 'components/Select': Select,
|
||||||
// 'components/Navigation': Navigation,
|
'components/Navigation': Navigation,
|
||||||
'components/Alert': Alert,
|
'components/Alert': Alert,
|
||||||
'components/LinkButton': LinkButton,
|
'components/LinkButton': LinkButton,
|
||||||
'components/Checkbox': Checkbox,
|
'components/Checkbox': Checkbox,
|
||||||
|
113
js/src/common/components/Navigation.tsx
Normal file
113
js/src/common/components/Navigation.tsx
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import Component, { ComponentProps } from '../Component';
|
||||||
|
import Button from './Button';
|
||||||
|
import LinkButton from './LinkButton';
|
||||||
|
|
||||||
|
import History from '../../forum/utils/History';
|
||||||
|
|
||||||
|
export interface NavigationProps extends ComponentProps {
|
||||||
|
/**
|
||||||
|
* The name of a class to set on the root element.
|
||||||
|
*/
|
||||||
|
className?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not to show a button to toggle the app's drawer if
|
||||||
|
* there is no more history to pop.
|
||||||
|
*/
|
||||||
|
drawer?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `Navigation` component displays a set of navigation buttons. Typically
|
||||||
|
* this is just a back button which pops the app's History. If the user is on
|
||||||
|
* the root page and there is no history to pop, then in some instances it may
|
||||||
|
* show a button that toggles the app's drawer.
|
||||||
|
*
|
||||||
|
* If the app has a pane, it will also include a 'pin' button which toggles the
|
||||||
|
* pinned state of the pane.
|
||||||
|
*/
|
||||||
|
export default class Navigation extends Component<NavigationProps> {
|
||||||
|
className?: string;
|
||||||
|
drawer: boolean;
|
||||||
|
|
||||||
|
constructor(options: { className?: string; drawer?: boolean } = {}) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.className = options.className;
|
||||||
|
this.drawer = !!options.drawer;
|
||||||
|
}
|
||||||
|
|
||||||
|
view() {
|
||||||
|
const { history, pane }: { history: History; pane: any } = app;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={'Navigation ButtonGroup ' + (this.className || '')}
|
||||||
|
onmouseenter={pane && pane.show.bind(pane)}
|
||||||
|
onmouseleave={pane && pane.onmouseleave.bind(pane)}
|
||||||
|
>
|
||||||
|
{history.canGoBack() ? [this.getBackButton(), this.getPaneButton()] : this.getDrawerButton()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the back button.
|
||||||
|
*/
|
||||||
|
protected getBackButton() {
|
||||||
|
const { history } = app;
|
||||||
|
const previous = history.getPrevious() || {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LinkButton
|
||||||
|
className="Button Navigation-back Button--icon"
|
||||||
|
href={history.backUrl()}
|
||||||
|
icon="fas fa-chevron-left"
|
||||||
|
title={previous.title}
|
||||||
|
onclick={(e) => {
|
||||||
|
if (e.shiftKey || e.ctrlKey || e.metaKey || e.which === 2) return;
|
||||||
|
e.preventDefault();
|
||||||
|
history.back();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the pane pinned toggle button.
|
||||||
|
*/
|
||||||
|
protected getPaneButton() {
|
||||||
|
const { pane } = app;
|
||||||
|
|
||||||
|
if (!pane || !pane.active) return '';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={'Button Button--icon Navigation-pin' + (pane.pinned ? ' active' : '')}
|
||||||
|
onclick={pane.togglePinned.bind(pane)}
|
||||||
|
icon="fas fa-thumbtack"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the drawer toggle button.
|
||||||
|
*/
|
||||||
|
protected getDrawerButton() {
|
||||||
|
if (!this.drawer) return '';
|
||||||
|
|
||||||
|
const { drawer } = app;
|
||||||
|
const user = app.session.user;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={'Button Button--icon Navigation-drawer' + (user && user.newNotificationCount() ? ' new' : '')}
|
||||||
|
onclick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
drawer.show();
|
||||||
|
}}
|
||||||
|
icon="fas fa-bars"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -35,10 +35,8 @@ export default class Drawer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the drawer.
|
* Show the drawer.
|
||||||
*
|
|
||||||
* @public
|
|
||||||
*/
|
*/
|
||||||
show() {
|
public show() {
|
||||||
$('#app').addClass('drawerOpen');
|
$('#app').addClass('drawerOpen');
|
||||||
|
|
||||||
this.$backdrop = $('<div/>')
|
this.$backdrop = $('<div/>')
|
||||||
@@ -46,6 +44,6 @@ export default class Drawer {
|
|||||||
.appendTo('body')
|
.appendTo('body')
|
||||||
.click(() => this.hide());
|
.click(() => this.hide());
|
||||||
|
|
||||||
setTimeout(() => this.$backdrop.addClass('in'));
|
requestAnimationFrame(() => this.$backdrop!.addClass('in'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import Application from '../common/Application';
|
import Application from '../common/Application';
|
||||||
import History from './utils/History';
|
import History from './utils/History';
|
||||||
|
|
||||||
|
import Navigation from '../common/components/Navigation';
|
||||||
import HeaderPrimary from './components/HeaderPrimary';
|
import HeaderPrimary from './components/HeaderPrimary';
|
||||||
import HeaderSecondary from './components/HeaderSecondary';
|
import HeaderSecondary from './components/HeaderSecondary';
|
||||||
import Page from './components/Page';
|
import Page from './components/Page';
|
||||||
@@ -57,8 +58,8 @@ export default class Forum extends Application {
|
|||||||
this.routes[defaultAction].path = '/';
|
this.routes[defaultAction].path = '/';
|
||||||
this.history.push(defaultAction, this.translator.transText('core.forum.header.back_to_index_tooltip'), '/');
|
this.history.push(defaultAction, this.translator.transText('core.forum.header.back_to_index_tooltip'), '/');
|
||||||
|
|
||||||
// m.mount(document.getElementById('app-navigation'), Navigation.component({className: 'App-backControl', drawer: true}));
|
m.mount(document.getElementById('app-navigation'), new Navigation({ className: 'App-backControl', drawer: true }));
|
||||||
// m.mount(document.getElementById('header-navigation'), Navigation.component());
|
m.mount(document.getElementById('header-navigation'), new Navigation());
|
||||||
m.mount(document.getElementById('header-primary'), new HeaderPrimary());
|
m.mount(document.getElementById('header-primary'), new HeaderPrimary());
|
||||||
m.mount(document.getElementById('header-secondary'), new HeaderSecondary());
|
m.mount(document.getElementById('header-secondary'), new HeaderSecondary());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user