UNPKG

4.39 kBTypeScriptView Raw
1/*
2 * Copyright (c) Jupyter Development Team.
3 * Distributed under the terms of the Modified BSD License.
4 */
5
6import { TextItem } from '@jupyterlab/statusbar';
7import {
8 ITranslator,
9 nullTranslator,
10 TranslationBundle
11} from '@jupyterlab/translation';
12import { VDomModel, VDomRenderer } from '@jupyterlab/ui-components';
13import * as React from 'react';
14import { Notebook, NotebookMode } from '.';
15
16/**
17 * A pure function for rendering a Command/Edit mode component.
18 *
19 * @param props: the props for rendering the component.
20 *
21 * @returns a tsx component for command/edit mode.
22 */
23function CommandEditComponent(
24 props: CommandEditComponent.IProps
25): React.ReactElement<CommandEditComponent.IProps> {
26 const trans = (props.translator || nullTranslator).load('jupyterlab');
27 return (
28 <TextItem
29 source={trans.__('Mode: %1', props.modeNames[props.notebookMode])}
30 />
31 );
32}
33
34/**
35 * A namespace for CommandEditComponent statics.
36 */
37namespace CommandEditComponent {
38 /**
39 * The props for the CommandEditComponent.
40 */
41 export interface IProps {
42 /**
43 * The current mode of the current notebook.
44 */
45 notebookMode: NotebookMode;
46
47 /**
48 * Language translator.
49 */
50 translator?: ITranslator;
51
52 /**
53 * Mapping translating the names of modes.
54 */
55 modeNames: Record<NotebookMode, string>;
56 }
57}
58
59/**
60 * StatusBar item to display which notebook mode user is in.
61 */
62export class CommandEditStatus extends VDomRenderer<CommandEditStatus.Model> {
63 /**
64 * Construct a new CommandEdit status item.
65 */
66 constructor(translator?: ITranslator) {
67 super(new CommandEditStatus.Model());
68 this.translator = translator || nullTranslator;
69 this._trans = this.translator.load('jupyterlab');
70 this._modeNames = {
71 command: this._trans.__('Command'),
72 edit: this._trans.__('Edit')
73 };
74 }
75
76 /**
77 * Render the CommandEdit status item.
78 */
79 render(): JSX.Element | null {
80 if (!this.model) {
81 return null;
82 }
83 this.node.title = this._trans.__(
84 'Notebook is in %1 mode',
85 this._modeNames[this.model.notebookMode]
86 );
87 return (
88 <CommandEditComponent
89 notebookMode={this.model.notebookMode}
90 translator={this.translator}
91 modeNames={this._modeNames}
92 />
93 );
94 }
95
96 protected translator: ITranslator;
97 private _trans: TranslationBundle;
98 private readonly _modeNames: Record<NotebookMode, string>;
99}
100
101/**
102 * A namespace for CommandEdit statics.
103 */
104export namespace CommandEditStatus {
105 /**
106 * A VDomModel for the CommandEdit renderer.
107 */
108 export class Model extends VDomModel {
109 /**
110 * The current mode of the current notebook.
111 */
112 get notebookMode(): NotebookMode {
113 return this._notebookMode;
114 }
115
116 /**
117 * Set the current notebook for the model.
118 */
119 set notebook(notebook: Notebook | null) {
120 const oldNotebook = this._notebook;
121 if (oldNotebook !== null) {
122 oldNotebook.stateChanged.disconnect(this._onChanged, this);
123 oldNotebook.activeCellChanged.disconnect(this._onChanged, this);
124 oldNotebook.modelContentChanged.disconnect(this._onChanged, this);
125 }
126
127 const oldMode = this._notebookMode;
128 this._notebook = notebook;
129 if (this._notebook === null) {
130 this._notebookMode = 'command';
131 } else {
132 this._notebookMode = this._notebook.mode;
133 this._notebook.stateChanged.connect(this._onChanged, this);
134 this._notebook.activeCellChanged.connect(this._onChanged, this);
135 this._notebook.modelContentChanged.connect(this._onChanged, this);
136 }
137
138 this._triggerChange(oldMode, this._notebookMode);
139 }
140
141 /**
142 * On a change to the notebook, update the mode.
143 */
144 private _onChanged = (_notebook: Notebook) => {
145 const oldMode = this._notebookMode;
146 if (this._notebook) {
147 this._notebookMode = _notebook.mode;
148 } else {
149 this._notebookMode = 'command';
150 }
151 this._triggerChange(oldMode, this._notebookMode);
152 };
153
154 /**
155 * Trigger a state change for the renderer.
156 */
157 private _triggerChange(oldState: NotebookMode, newState: NotebookMode) {
158 if (oldState !== newState) {
159 this.stateChanged.emit(void 0);
160 }
161 }
162
163 private _notebookMode: NotebookMode = 'command';
164 private _notebook: Notebook | null = null;
165 }
166}