fix: aligned more to old shell
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -134,9 +134,15 @@
|
||||
<div class="tab-bar-tabs">
|
||||
<%= for tab <- @workbench.tabs do %>
|
||||
<div
|
||||
class={["tab", if(@workbench.active_tab == {tab.type, tab.id}, do: "active"), if(tab.is_transient, do: "transient")]}
|
||||
class={[
|
||||
"tab",
|
||||
if(@workbench.active_tab == {tab.type, tab.id}, do: "active"),
|
||||
if(tab.is_transient, do: "transient"),
|
||||
if(Workbench.dirty?(@workbench, tab.type, tab.id), do: "dirty")
|
||||
]}
|
||||
data-tab-type={tab.type}
|
||||
data-tab-id={tab.id}
|
||||
tabindex="0"
|
||||
>
|
||||
<button
|
||||
class="tab-select"
|
||||
@@ -148,20 +154,25 @@
|
||||
<span class="tab-icon"><%= raw(ShellData.activity_icon(tab_icon_id(tab))) %></span>
|
||||
<span class="tab-title"><%= tab_title(tab, @tab_meta) %></span>
|
||||
</button>
|
||||
<button
|
||||
class="tab-close"
|
||||
data-testid="tab-close"
|
||||
data-tab-type={tab.type}
|
||||
data-tab-id={tab.id}
|
||||
type="button"
|
||||
phx-click="close_tab"
|
||||
phx-value-type={tab.type}
|
||||
phx-value-id={tab.id}
|
||||
aria-label={translated("Close tab")}
|
||||
title={translated("Close tab")}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<div class="tab-actions">
|
||||
<%= if Workbench.dirty?(@workbench, tab.type, tab.id) do %>
|
||||
<span class="tab-dirty-indicator">●</span>
|
||||
<% end %>
|
||||
<button
|
||||
class="tab-close"
|
||||
data-testid="tab-close"
|
||||
data-tab-type={tab.type}
|
||||
data-tab-id={tab.id}
|
||||
type="button"
|
||||
phx-click="close_tab"
|
||||
phx-value-type={tab.type}
|
||||
phx-value-id={tab.id}
|
||||
aria-label={translated("Close tab")}
|
||||
title={translated("Close tab")}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -107,7 +107,7 @@ button {
|
||||
flex-shrink: 0;
|
||||
app-region: drag;
|
||||
-webkit-app-region: drag;
|
||||
padding-right: 10px;
|
||||
padding-right: calc(10px + var(--bds-titlebar-overlay-right, 0px));
|
||||
}
|
||||
|
||||
.window-titlebar-menu-bar {
|
||||
@@ -125,6 +125,10 @@ button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.window-titlebar.is-mac .window-titlebar-menu-bar {
|
||||
margin-left: max(var(--bds-titlebar-macos-left-inset, 78px), calc(6px + var(--bds-titlebar-overlay-left, 0px)));
|
||||
}
|
||||
|
||||
.window-titlebar-menu-button {
|
||||
height: 24px;
|
||||
border: none;
|
||||
@@ -142,6 +146,14 @@ button {
|
||||
background-color: var(--vscode-toolbar-hoverBackground);
|
||||
}
|
||||
|
||||
.window-titlebar-menu-button:focus,
|
||||
.window-titlebar-menu-button:focus-visible,
|
||||
.window-titlebar-action-button:focus,
|
||||
.window-titlebar-action-button:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.window-titlebar-drag-region {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
@@ -296,7 +308,7 @@ button {
|
||||
justify-content: center;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--vscode-titleBar-activeForeground);
|
||||
color: var(--vscode-activityBar-foreground);
|
||||
opacity: 0.6;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
@@ -319,7 +331,7 @@ button {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 2px;
|
||||
background-color: var(--vscode-titleBar-activeForeground);
|
||||
background-color: var(--vscode-activityBar-foreground);
|
||||
}
|
||||
|
||||
.activity-bar-item svg,
|
||||
@@ -551,6 +563,20 @@ button {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.tab-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tab-dirty-indicator {
|
||||
color: var(--vscode-editorWarning-foreground, #e2c08d);
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.tab-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -567,28 +593,63 @@ button {
|
||||
}
|
||||
|
||||
.tab-close {
|
||||
margin-left: auto;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: inline-flex;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 15px;
|
||||
line-height: 1;
|
||||
color: var(--vscode-descriptionForeground);
|
||||
border-radius: 4px;
|
||||
color: var(--vscode-icon-foreground, #c5c5c5);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tab:hover .tab-close {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.tab.active .tab-close {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.tab-close:hover {
|
||||
opacity: 1 !important;
|
||||
background-color: var(--vscode-toolbar-hoverBackground);
|
||||
color: var(--vscode-tab-activeForeground);
|
||||
}
|
||||
|
||||
.tab-close:active {
|
||||
background-color: var(--vscode-toolbar-activeBackground, rgba(99, 102, 103, 0.31));
|
||||
}
|
||||
|
||||
.tab.dirty .tab-dirty-indicator {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tab.dirty .tab-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab.dirty:hover .tab-close {
|
||||
display: flex;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.tab.dirty:hover .tab-dirty-indicator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab:focus-visible {
|
||||
outline: 1px solid var(--vscode-focusBorder, #007fd4);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.output-item-details {
|
||||
margin: 4px 0 0;
|
||||
padding: 8px;
|
||||
|
||||
@@ -50,11 +50,52 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
window.localStorage.setItem(key, String(width));
|
||||
};
|
||||
|
||||
const syncTitlebarOverlayInsets = () => {
|
||||
const rootStyle = document.documentElement.style;
|
||||
const setInsets = (left, right) => {
|
||||
rootStyle.setProperty("--bds-titlebar-overlay-left", `${left}px`);
|
||||
rootStyle.setProperty("--bds-titlebar-overlay-right", `${right}px`);
|
||||
};
|
||||
|
||||
const overlay = navigator.windowControlsOverlay;
|
||||
|
||||
if (!overlay) {
|
||||
setInsets(0, 0);
|
||||
return () => {};
|
||||
}
|
||||
|
||||
const updateInsets = () => {
|
||||
if (!overlay.visible) {
|
||||
setInsets(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
const titlebarRect = overlay.getTitlebarAreaRect();
|
||||
const viewportWidth = window.innerWidth || document.documentElement.clientWidth || titlebarRect.right;
|
||||
const leftInset = Math.max(0, Math.round(titlebarRect.left));
|
||||
const rightInset = Math.max(0, Math.round(viewportWidth - titlebarRect.right));
|
||||
setInsets(leftInset, rightInset);
|
||||
};
|
||||
|
||||
const onGeometryChange = () => updateInsets();
|
||||
const onResize = () => updateInsets();
|
||||
|
||||
updateInsets();
|
||||
overlay.addEventListener("geometrychange", onGeometryChange);
|
||||
window.addEventListener("resize", onResize);
|
||||
|
||||
return () => {
|
||||
overlay.removeEventListener("geometrychange", onGeometryChange);
|
||||
window.removeEventListener("resize", onResize);
|
||||
};
|
||||
};
|
||||
|
||||
const Hooks = {
|
||||
AppShell: {
|
||||
mounted() {
|
||||
this.syncStoredLayout();
|
||||
this.syncStoredUiLanguage();
|
||||
this.destroyOverlaySync = syncTitlebarOverlayInsets();
|
||||
|
||||
this.handleMouseDown = (event) => {
|
||||
const handle = event.target.closest("[data-role='resize-handle']");
|
||||
@@ -126,6 +167,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
this.el.removeEventListener("mousedown", this.handleMouseDown);
|
||||
this.el.removeEventListener("change", this.handleChange);
|
||||
window.removeEventListener("bds:native-menu-action", this.handleNativeMenuAction);
|
||||
if (this.destroyOverlaySync) {
|
||||
this.destroyOverlaySync();
|
||||
}
|
||||
},
|
||||
|
||||
syncStoredLayout() {
|
||||
|
||||
@@ -126,4 +126,23 @@ defmodule BDS.UI.ShellTest do
|
||||
assert css =~ ".status-bar-item.language-badge"
|
||||
assert css =~ ".status-bar-item.offline-badge"
|
||||
end
|
||||
|
||||
test "desktop shell assets keep old activity, tab, focus, and titlebar overlay parity rules" do
|
||||
css = File.read!("/Users/gb/Projects/bDS2/priv/ui/app.css")
|
||||
live_js = File.read!("/Users/gb/Projects/bDS2/priv/ui/live.js")
|
||||
template = File.read!("/Users/gb/Projects/bDS2/lib/bds/desktop/shell_live/index.html.heex")
|
||||
|
||||
assert css =~ "color: var(--vscode-activityBar-foreground)"
|
||||
assert css =~ ".tab-actions"
|
||||
assert css =~ ".tab-dirty-indicator"
|
||||
assert css =~ ".tab.dirty .tab-close"
|
||||
assert css =~ ".tab:focus-visible"
|
||||
assert css =~ ".window-titlebar-action-button:focus"
|
||||
assert css =~ "padding-right: calc(10px + var(--bds-titlebar-overlay-right, 0px));"
|
||||
assert live_js =~ "windowControlsOverlay"
|
||||
assert live_js =~ "geometrychange"
|
||||
assert live_js =~ "--bds-titlebar-overlay-left"
|
||||
assert template =~ "tab-actions"
|
||||
assert template =~ "tab-dirty-indicator"
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user