1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | import { ellipsesIcon } from '@jupyterlab/ui-components';
|
7 | import { Widget } from '@lumino/widgets';
|
8 | import { Message } from '@lumino/messaging';
|
9 | import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | const PLACEHOLDER_CLASS = 'jp-Placeholder';
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | const INPUT_PROMPT_CLASS = 'jp-Placeholder-prompt jp-InputPrompt';
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | const OUTPUT_PROMPT_CLASS = 'jp-Placeholder-prompt jp-OutputPrompt';
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | const CONTENT_CLASS = 'jp-Placeholder-content';
|
30 |
|
31 |
|
32 |
|
33 |
|
34 | const INPUT_PLACEHOLDER_CLASS = 'jp-InputPlaceholder';
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | const OUTPUT_PLACEHOLDER_CLASS = 'jp-OutputPlaceholder';
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | export interface IPlaceholderOptions {
|
45 | |
46 |
|
47 |
|
48 | promptClass?: string;
|
49 | |
50 |
|
51 |
|
52 | callback: (e: MouseEvent) => void;
|
53 | |
54 |
|
55 |
|
56 | text?: string;
|
57 |
|
58 | |
59 |
|
60 |
|
61 | translator?: ITranslator;
|
62 | }
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 | export class Placeholder extends Widget {
|
72 | |
73 |
|
74 |
|
75 | constructor(options: IPlaceholderOptions) {
|
76 | const node = document.createElement('div');
|
77 |
|
78 | super({ node });
|
79 | const trans = (options.translator ?? nullTranslator).load('jupyterlab');
|
80 | const innerNode = document.createElement('div');
|
81 | innerNode.className = options.promptClass ?? '';
|
82 | node.insertAdjacentHTML('afterbegin', innerNode.outerHTML);
|
83 | this._cell = document.createElement('div');
|
84 | this._cell.classList.add(CONTENT_CLASS);
|
85 | this._cell.title = trans.__('Click to expand');
|
86 | const container = this._cell.appendChild(document.createElement('div'));
|
87 | container.classList.add('jp-Placeholder-contentContainer');
|
88 | this._textContent = container.appendChild(document.createElement('span'));
|
89 | this._textContent.className = 'jp-PlaceholderText';
|
90 | this._textContent.innerText = options.text ?? '';
|
91 | node.appendChild(this._cell);
|
92 | ellipsesIcon.element({
|
93 | container: container.appendChild(document.createElement('span')),
|
94 | className: 'jp-MoreHorizIcon',
|
95 | elementPosition: 'center',
|
96 | height: 'auto',
|
97 | width: '32px'
|
98 | });
|
99 |
|
100 | this.addClass(PLACEHOLDER_CLASS);
|
101 | this._callback = options.callback;
|
102 | }
|
103 |
|
104 | |
105 |
|
106 |
|
107 | set text(t: string) {
|
108 | this._textContent.innerText = t;
|
109 | }
|
110 | get text(): string {
|
111 | return this._textContent.innerText;
|
112 | }
|
113 |
|
114 | protected onAfterAttach(msg: Message): void {
|
115 | super.onAfterAttach(msg);
|
116 | this.node.addEventListener('click', this._callback);
|
117 | }
|
118 |
|
119 | protected onBeforeDetach(msg: Message): void {
|
120 | this.node.removeEventListener('click', this._callback);
|
121 | super.onBeforeDetach(msg);
|
122 | }
|
123 |
|
124 | private _callback: (e: MouseEvent) => void;
|
125 | private _cell: HTMLElement;
|
126 | private _textContent: HTMLSpanElement;
|
127 | }
|
128 |
|
129 |
|
130 |
|
131 |
|
132 | export class InputPlaceholder extends Placeholder {
|
133 | |
134 |
|
135 |
|
136 | constructor(options: IPlaceholderOptions) {
|
137 | super({ ...options, promptClass: INPUT_PROMPT_CLASS });
|
138 | this.addClass(INPUT_PLACEHOLDER_CLASS);
|
139 | }
|
140 | }
|
141 |
|
142 |
|
143 |
|
144 |
|
145 | export class OutputPlaceholder extends Placeholder {
|
146 | |
147 |
|
148 |
|
149 | constructor(options: IPlaceholderOptions) {
|
150 | super({ ...options, promptClass: OUTPUT_PROMPT_CLASS });
|
151 | this.addClass(OUTPUT_PLACEHOLDER_CLASS);
|
152 | }
|
153 | }
|