Skip to content

Commit bbf69f3

Browse files
committed
Show coloured progress in a responsive homepage terminal
1 parent c8d378f commit bbf69f3

13 files changed

Lines changed: 196 additions & 7 deletions

File tree

‎docs/_ext/demo.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,5 +174,6 @@ def setup(app: Sphinx) -> dict[str, typing.Any]:
174174
app.add_css_file('vendor/xterm.css')
175175
app.add_css_file('livecode/livecode.css')
176176
app.add_js_file('vendor/xterm.js')
177+
app.add_js_file('vendor/addon-fit.js')
177178
app.add_js_file('livecode/livecode.js')
178179
return {'parallel_read_safe': True, 'parallel_write_safe': True}

‎docs/_static/demos/homepage-quickstart.svg‎

Lines changed: 60 additions & 0 deletions
Loading

‎docs/_static/livecode/livecode.css‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
.demo-controls {
3232
display: flex;
33+
flex-wrap: wrap;
3334
align-items: center;
3435
gap: 0.75rem;
3536
padding: 0.5rem 0.75rem;
@@ -73,3 +74,7 @@
7374
padding: 0.5rem;
7475
overflow-x: auto;
7576
}
77+
78+
.demo-terminal .xterm-viewport {
79+
overflow-y: auto;
80+
}

‎docs/_static/livecode/livecode.js‎

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,29 @@ function keepHighlightedHomepageSource(container, editor, controls, source) {
123123
controls.append(edit);
124124
}
125125

126+
/**
127+
* @param {Terminal} terminal
128+
* @param {HTMLElement} host
129+
* @returns {() => void}
130+
*/
131+
function fitTerminalWidth(terminal, host) {
132+
/** @type {FitAddon.FitAddon} */
133+
const addon = new FitAddon.FitAddon();
134+
terminal.loadAddon(addon);
135+
/** @type {() => void} */
136+
const fit = () => {
137+
/** @type {{cols: number, rows: number} | undefined} */
138+
const dimensions = addon.proposeDimensions();
139+
if (dimensions && dimensions.cols !== terminal.cols) {
140+
terminal.resize(dimensions.cols, terminal.rows);
141+
}
142+
};
143+
/** @type {ResizeObserver} */
144+
const observer = new ResizeObserver(fit);
145+
observer.observe(host);
146+
return fit;
147+
}
148+
126149
function createPanel(container, source) {
127150
const editor = document.createElement('textarea');
128151
editor.className = 'demo-editor';
@@ -143,6 +166,9 @@ function createPanel(container, source) {
143166

144167
const screen = document.createElement('div');
145168
screen.className = 'demo-terminal';
169+
/** @type {HTMLDivElement} */
170+
const terminalHost = document.createElement('div');
171+
screen.append(terminalHost);
146172

147173
const controls = document.createElement('div');
148174
controls.className = 'demo-controls';
@@ -153,12 +179,14 @@ function createPanel(container, source) {
153179

154180
const terminal = new Terminal({
155181
cols: COLUMNS,
156-
rows: 12,
182+
rows: container.closest('.home-quickstart') ? 3 : 12,
157183
convertEol: true,
158184
fontSize: 13,
159185
theme: {background: '#101418', foreground: '#d6e2ef'},
160186
});
161-
terminal.open(screen);
187+
terminal.open(terminalHost);
188+
/** @type {() => void} */
189+
const fitWidth = fitTerminalWidth(terminal, terminalHost);
162190

163191
const panel = {
164192
terminal,
@@ -195,6 +223,8 @@ function createPanel(container, source) {
195223
panel.setStatus('idle');
196224
return;
197225
}
226+
await new Promise(resolve => requestAnimationFrame(resolve));
227+
fitWidth();
198228
panel.setStatus('ready');
199229
timeoutHandle = setTimeout(() => {
200230
terminal.write('\r\n\x1b[33mStopped after 30 seconds.\x1b[0m\r\n');
@@ -204,7 +234,7 @@ function createPanel(container, source) {
204234
worker.postMessage({
205235
type: 'run',
206236
code: editor.value,
207-
columns: COLUMNS,
237+
columns: terminal.cols,
208238
});
209239
});
210240

@@ -224,7 +254,7 @@ const NON_RUNNABLE_DEMOS = new Set([
224254
]);
225255

226256
document.addEventListener('DOMContentLoaded', () => {
227-
if (typeof Terminal === 'undefined') return;
257+
if (typeof Terminal === 'undefined' || typeof FitAddon === 'undefined') return;
228258
for (const container of document.querySelectorAll('.demo-run')) {
229259
if (NON_RUNNABLE_DEMOS.has(container.dataset.demo)) {
230260
container.textContent =
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2019, The xterm.js authors (https://github.com/xtermjs/xterm.js)
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

‎docs/_static/vendor/README.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
| File | Source | Version | License |
44
| --- | --- | --- | --- |
55
| `xterm.js`, `xterm.css` | `@xterm/xterm` | 5.5.0 | MIT (`LICENSE-xterm.txt`) |
6+
| `addon-fit.js`, `addon-fit.js.map` | `@xterm/addon-fit` | 0.10.0 | MIT (`LICENSE-addon-fit.txt`) |
67

78
Update (bump the version in both commands and this table):
89

@@ -14,3 +15,13 @@ cp package/css/xterm.css docs/_static/vendor/xterm.css
1415
cp package/LICENSE docs/_static/vendor/LICENSE-xterm.txt
1516
rm -rf package xterm-xterm-5.5.0.tgz
1617
```
18+
19+
Update the matching terminal sizing addon:
20+
21+
```bash
22+
npm pack @xterm/addon-fit@0.10.0
23+
tar -xzf xterm-addon-fit-0.10.0.tgz
24+
cp package/lib/addon-fit.js package/lib/addon-fit.js.map docs/_static/vendor/
25+
cp package/LICENSE docs/_static/vendor/LICENSE-addon-fit.txt
26+
rm -rf package xterm-addon-fit-0.10.0.tgz
27+
```

‎docs/_static/vendor/addon-fit.js‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎docs/_static/vendor/addon-fit.js.map‎

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎docs/examples/_registry.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ def svg_path(self) -> pathlib.Path:
5757

5858

5959
DEMOS: tuple[Demo, ...] = (
60+
Demo(
61+
'homepage/quickstart', 'A percentage and a coloured bar', term_width=60
62+
),
6063
Demo('howto/colors', 'Fixed and gradient bar colors'),
6164
Demo('howto/custom-widget', 'The current job phase', term_width=60),
6265
Demo(

‎docs/examples/homepage/__init__.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Examples for the documentation homepage."""

0 commit comments

Comments
 (0)