Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tab bar instructions to docsite #1779

Merged
merged 1 commit into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import { Card, CardGroup } from "@site/src/components/card.tsx";

# Welcome to Wave Terminal

Wave is an [open-source](https://github.com/wavetermdev/waveterm) terminal that combines traditional terminal features with graphical capabilities like file previews, web browsing, and AI assistance. It runs on MacOS, Linux, and Windows ([Getting Started](./gettingstarted)).
Wave is an [open-source](https://github.com/wavetermdev/waveterm) terminal that combines traditional terminal features with graphical capabilities like file previews, web browsing, and AI assistance. It runs on MacOS, Linux, and Windows.

Modern development involves constantly switching between terminals and browsers - checking documentation, previewing files, monitoring systems, and using AI tools. Wave brings these graphical tools directly into the terminal, letting you control them from the command line. This means you can stay in your terminal workflow while still having access to the visual interfaces you need.

Check out [Getting Started](./gettingstarted) for installation instructions.

![Wave Screenshot](./img/wave-screenshot.webp)

<CardGroup>
Expand Down
87 changes: 4 additions & 83 deletions docs/docs/layout.mdx
Original file line number Diff line number Diff line change
@@ -1,89 +1,10 @@
---
sidebar_position: 3.5
sidebar_class_name: hidden
id: "layout"
title: "Tab Layout System"
---

import { PlatformProvider, PlatformSelectorButton } from "@site/src/components/platformcontext.tsx";
import { Kbd } from "@site/src/components/kbd.tsx";
import { Redirect } from "@docusaurus/router";

<PlatformProvider>
<PlatformSelectorButton/>
<Redirect to="/tabs#tab-layout-system" />

![screenshot showing a block being dragged over another block, with the placeholder depicting a out-of-line before outer drop](./img/drag-edge.png)

## Layout system under the hood

:::info

**Definitions**

- Layout tree: the in-memory representation of a tab layout, comprised of nodes
- Node: An entry in the layout tree, either a single block (a leaf) or an ordered list of nodes. Defines a tiling direction (row or column) and a unitless size
- Block: The contents of a leaf in the layout tree, defines what contents is displayed at the given layout location

:::

Our layout system emulates the [CSS Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox) system, comprising of a tree of columns and rows. Under the hood, the layout is represented as an n-tree, where each node in the tree is either a single block, or a list of nodes. Each level in the tree alternates the direction in which it tiles (level 1 tiles as a row, level 2 as a column, level 3 as a row, etc.).

## Layout actions

### Add a new block

You can add new blocks by selecting a widget from the right sidebar.

Starting at the topmost level of the tree, since the first level tiles as a row, new blocks will be added to the right side of existing blocks. Once there are 5 blocks across, new blocks will begin being added below existing blocks, starting from the right side and working to the left. As a new block gets added below an existing one, the node containing the existing block is converted from a single-block node to a list node and the existing block definition is moved one level deeper in the tree as the first element of the node list. New blocks will always be added to the last-available node in the deepest level, where available is defined as having less than five children. We don't set a limit on the number of blocks in a tab, but you may experience degraded performance past around 25 blocks.

While we define a 5-child limit for each node in the tree when automatically placing new blocks, there is no actual limit to the number of children a node can hold. After the block is placed, you are free to move it wherever in the layout

### Delete a block

You can delete blocks by clicking the <i className="fa-sharp fa-xmark-large"/> button in the top-right corner of the block, by right-clicking on the block header and selecting "Close Block" from the context menu, or by running the [`wsh deleteblock` command](./wsh-reference#deleteblock). Alternatively, the currently focused block/widget can be closed by pressing <Kbd k="Cmd:w"/>

When you delete a block, the layout tree will be automatically adjusted to minimize the tree depth.

### Move a block

You can move blocks by clicking on the block header and dragging the block around the tab. You will see placeholders appear to show where the block will land when you drop it.

There are 7 different drop targets for any given block. A block is divided into quadrants along its diagonals. If the block is tiling as a row (left-to-right), dropping a block into the left or right quadrant will place the dropped block in the same level as the targeted block. This can be considered dropping the block inline. If you drop the block out of line (in quadrants corresponding to opposite tiling direction), the block will either be placed one level above or one level below the targeted block. Dropping the block towards the outside will place it in the same level as the target block's parent, while dropping it towards the center of the block will create a new level, where both the target block and the dropped block will be moved. The middle fifth of the block is reserved for the swap action. Dropping a block here will cause the target block and the dropped block to swap positions in the layout.

<video width="100%" height="100%" playsinline autoplay muted controls>
<source src="./img/drag-move-24fps-crf43.mp4" type="video/mp4" />
</video>

#### Possible block movements

:::note
All block movements except for Swap will cause the rest of the layout to shift to accommodate the block's new displacement.
:::

![screenshot showing a block being dragged over another block, with the placeholder depicting a swap movement](./img/drag-swap.png)
![annotated example showing the drop targets within a block](./img/block-drag-example.jpg)

1. Inline before: Drops the block under the same node as the target block, placing it before the target in the same tiling direction
2. Inline after: Drops the block under the same node as the target block, placing it after the target in the same tiling direction
3. Out-of-line before outer: Drops the block before the target block's parent node in the opposite tiling direction
4. Out-of-line before inner: Segments the target block, creating a new node in the tree. Places the dropped block before the target block in the opposite tiling direction.
5. Out-of-line after inner: Segments the target block, creating a new node in the tree. Places the dropped block after the target block in the opposite tiling direction.
6. Out-of-line after outer: Drops the block after the target block's parent node in the opposite tiling direction
7. Swap: Swaps the position of the dropped block and the targeted block in the layout, preserving the rest of the layout

### Resize a block

<video width="100%" height="100%" playsinline autoplay muted controls>
<source src="./img/resize-24fps-crf43.mp4" type="video/mp4" />
</video>

![screenshot showing the line that appears when the cursor hovers over the margin of a block, indicating which blocks
will be resized by dragging the margin](./img/node-resize.png)

You do not directly resize a block. Rather, you resize the nodes containing the blocks. If you hover your mouse over the margin of a block, you will see the cursor change to <i className="fa-sharp fa-arrows-left-right"/> or <i className="fa-sharp fa-arrows-up-down"/> to indicate the direction the node can be resized. You will also see a line appear after 500ms to show you how many blocks will be resized by moving that margin. Clicking and dragging on this margin will cause the block(s) to get resized.

Node sizes are unitless values. The ratio of all node sizes at a given tree level determines the displacement of each node. If you move a block and its node is deleted, the other nodes at the given tree level will adjust their sizes to account for the new size ratio.

## Change the gap size between blocks

The gap between blocks defaults to 3px, but this value can be changed by modifying the `window:tilegapsize` configuration value. See [Configuration](./config) for more information on how to change configuration values.

</PlatformProvider>
<!-- The contents of this page has moved to the tabs.mdx file under the "Tab Layout System" section. -->
134 changes: 134 additions & 0 deletions docs/docs/tabs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
sidebar_position: 3.2
id: "tabs"
title: "Tabs"
---

import { PlatformProvider, PlatformSelectorButton } from "@site/src/components/platformcontext.tsx";
import { Kbd } from "@site/src/components/kbd.tsx";

<PlatformProvider>

Tabs in are collections of [Widgets](./widgets) that can be arranged into tiled dashboards. You can create as many tabs as you want within a given workspace to help organize your workflows.

## Tab Bar

The tab bar is located at the top of the window and shows all tabs within a given workspace. You can click on a tab to switch to it. When switching tabs, any commands in the previous tab will continue running and any unsaved work will be persisted until you return to it. If you close the window or switch workspaces within the same window, that work will be lost.

<PlatformSelectorButton />

### Creating a new tab

You can create a new tab by clicking the <i className="fa-sharp fa-plus" title="plus"/> button to the right of the tabs in the tab bar, or by pressing <Kbd k="Cmd:t"/> on the keyboard. This will also focus you to the new tab.

### Closing a tab

You can close a tab by hovering over it and clicking the <i className="fa-sharp fa-xmark-large" title="x"/> button that appears, or by pressing <Kbd k="Cmd:Shift:w"/> on the keyboard. You can also close a tab by [closing all the blocks](#delete-a-block) within it.

Closing a block is a destructive action that will stop any running processes and discard any unsaved work. This cannot be undone.

### Rearranging tabs

You can rearrange tabs by dragging them around within the tab bar.

### Switching tabs

You can switch to an existing tab by clicking on it in the tab bar. You can also use the following shortcuts:

| Key | Function |
| ------------------ | -------------------- |
| <Kbd k="Cmd:1-9"/> | Switch to tab number |
| <Kbd k="Cmd:["/> | Switch tab left |
| <Kbd k="Cmd:]"/> | Switch tab right |

### Pinning a tab

Pinning a tab makes it harder to close accidentally. You can pin a tab by right-clicking on it and selecting "Pin Tab" from the context menu that appears. You can also pin a tab by dragging it to a lesser index than an existing pinned tab. When a tab is pinned, the <i className="fa-sharp fa-xmark-large" title="x"/> button for the tab will be replaced with a <i className="fa-sharp fa-thumbtack" title="pin"/> button. Clicking this button will unpin the tab. You can also unpin a tab by dragging it to an index higher than an existing unpinned tab.

## Tab Layout System

The tabs are comprised of tiled blocks. The contents of each block is a single widget. You can move blocks around and arrange them into layouts that best-suit your workflow. You can also magnify blocks to focus on a specific widget.

![screenshot showing a block being dragged over another block, with the placeholder depicting a out-of-line before outer drop](./img/drag-edge.png)

### Layout system under the hood

:::info

**Definitions**

- Layout tree: the in-memory representation of a tab layout, comprised of nodes
- Node: An entry in the layout tree, either a single block (a leaf) or an ordered list of nodes. Defines a tiling direction (row or column) and a unitless size
- Block: The contents of a leaf in the layout tree, defines what contents is displayed at the given layout location

:::

Our layout system emulates the [CSS Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox) system, comprising of a tree of columns and rows. Under the hood, the layout is represented as an n-tree, where each node in the tree is either a single block, or a list of nodes. Each level in the tree alternates the direction in which it tiles (level 1 tiles as a row, level 2 as a column, level 3 as a row, etc.).

### Layout actions

<PlatformSelectorButton />

#### Add a new block

You can add new blocks by selecting a widget from the right sidebar.

Starting at the topmost level of the tree, since the first level tiles as a row, new blocks will be added to the right side of existing blocks. Once there are 5 blocks across, new blocks will begin being added below existing blocks, starting from the right side and working to the left. As a new block gets added below an existing one, the node containing the existing block is converted from a single-block node to a list node and the existing block definition is moved one level deeper in the tree as the first element of the node list. New blocks will always be added to the last-available node in the deepest level, where available is defined as having less than five children. We don't set a limit on the number of blocks in a tab, but you may experience degraded performance past around 25 blocks.

While we define a 5-child limit for each node in the tree when automatically placing new blocks, there is no actual limit to the number of children a node can hold. After the block is placed, you are free to move it wherever in the layout

#### Delete a block

You can delete blocks by clicking the <i className="fa-sharp fa-xmark-large" title="x"/> button in the top-right corner of the block, by right-clicking on the block header and selecting "Close Block" from the context menu, or by running the [`wsh deleteblock` command](./wsh-reference#deleteblock). Alternatively, the currently focused block/widget can be closed by pressing <Kbd k="Cmd:w"/>

When you delete a block, the layout tree will be automatically adjusted to minimize the tree depth.

#### Move a block

You can move blocks by clicking on the block header and dragging the block around the tab. You will see placeholders appear to show where the block will land when you drop it.

There are 7 different drop targets for any given block. A block is divided into quadrants along its diagonals. If the block is tiling as a row (left-to-right), dropping a block into the left or right quadrant will place the dropped block in the same level as the targeted block. This can be considered dropping the block inline. If you drop the block out of line (in quadrants corresponding to opposite tiling direction), the block will either be placed one level above or one level below the targeted block. Dropping the block towards the outside will place it in the same level as the target block's parent, while dropping it towards the center of the block will create a new level, where both the target block and the dropped block will be moved. The middle fifth of the block is reserved for the swap action. Dropping a block here will cause the target block and the dropped block to swap positions in the layout.

<video width="100%" height="100%" playsinline autoplay muted controls>
<source src="./img/drag-move-24fps-crf43.mp4" type="video/mp4" />
</video>

##### Possible block movements

:::note
All block movements except for Swap will cause the rest of the layout to shift to accommodate the block's new displacement.
:::

![screenshot showing a block being dragged over another block, with the placeholder depicting a swap movement](./img/drag-swap.png)
![annotated example showing the drop targets within a block](./img/block-drag-example.jpg)

1. Inline before: Drops the block under the same node as the target block, placing it before the target in the same tiling direction
2. Inline after: Drops the block under the same node as the target block, placing it after the target in the same tiling direction
3. Out-of-line before outer: Drops the block before the target block's parent node in the opposite tiling direction
4. Out-of-line before inner: Segments the target block, creating a new node in the tree. Places the dropped block before the target block in the opposite tiling direction.
5. Out-of-line after inner: Segments the target block, creating a new node in the tree. Places the dropped block after the target block in the opposite tiling direction.
6. Out-of-line after outer: Drops the block after the target block's parent node in the opposite tiling direction
7. Swap: Swaps the position of the dropped block and the targeted block in the layout, preserving the rest of the layout

#### Resize a block

<video width="100%" height="100%" playsinline autoplay muted controls>
<source src="./img/resize-24fps-crf43.mp4" type="video/mp4" />
</video>

![screenshot showing the line that appears when the cursor hovers over the margin of a block, indicating which blocks
will be resized by dragging the margin](./img/node-resize.png)

You do not directly resize a block. Rather, you resize the nodes containing the blocks. If you hover your mouse over the margin of a block, you will see the cursor change to <i className="fa-sharp fa-arrows-left-right" title="left/right arrows"/> or <i className="fa-sharp fa-arrows-up-down" title="up/down arrows"/> to indicate the direction the node can be resized. You will also see a line appear after 500ms to show you how many blocks will be resized by moving that margin. Clicking and dragging on this margin will cause the block(s) to get resized.

Node sizes are unitless values. The ratio of all node sizes at a given tree level determines the displacement of each node. If you move a block and its node is deleted, the other nodes at the given tree level will adjust their sizes to account for the new size ratio.

### Magnify a block

You can magnify a block by clicking the <i className="custom-icon-inline custom-icon-magnify-disabled" title="magnify"/> button or by pressing <Kbd k="Cmd:m"/> on the keyboard. You can then un-magnify a block by clicking the <i className="custom-icon-inline custom-icon-magnify-enabled" title="un-magnify"/> button or by pressing <Kbd k="Cmd:m"/> again.

### Change the gap size between blocks

The gap between blocks defaults to 3px, but this value can be changed by modifying the `window:tilegapsize` configuration value. See [Configuration](./config) for more information on how to change configuration values.

</PlatformProvider>
1 change: 1 addition & 0 deletions docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const config: Config = {
},
},
],
"docusaurus-plugin-sass",
].filter((v) => v),
themes: [
["classic", { customCss: "src/css/custom.css" }],
Expand Down
2 changes: 2 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
"@mdx-js/react": "^3.0.0",
"@waveterm/docusaurus-og": "https://github.com/wavetermdev/docusaurus-og",
"clsx": "^2.1.1",
"docusaurus-plugin-sass": "^0.2.6",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"remark-gfm": "^4.0.0",
"remark-typescript-code-import": "^1.0.1",
"sass": "^1.83.4",
"ua-parser-js": "^2.0.0"
},
"devDependencies": {
Expand Down
18 changes: 18 additions & 0 deletions docs/src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ body .markdown h2 {
-webkit-mask: url(/img/workspace.svg) no-repeat center / contain;
}

.custom-icon-magnify-enabled:before {
content: "";
mask: url(/img/magnify-enabled.svg) no-repeat center / contain;
-webkit-mask: url(/img/magnify-enabled.svg) no-repeat center / contain;
margin-bottom: -2px;
}

.custom-icon-magnify-disabled:before {
content: "";
mask: url(/img/magnify-disabled.svg) no-repeat center / contain;
-webkit-mask: url(/img/magnify-disabled.svg) no-repeat center / contain;
margin-bottom: -2px;
}

img[src*="#left"] {
float: left;
margin: 0 10px 10px 0;
Expand All @@ -95,3 +109,7 @@ img[src*="#center"] {
display: block;
margin: auto;
}

.hidden {
display: none;
}
Loading
Loading