webui: convert SketchViewModeSelect to use SketchTailwindElement with Tailwind CSS
Replace LitElement shadow DOM component with SketchTailwindElement base class
to use Tailwind CSS utility classes instead of component-scoped CSS styles.
Also adds tailwind support for CSS container queries in addition to media
queries.
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s0eeb80dd54594375k
diff --git a/webui/src/web-components/sketch-view-mode-select.ts b/webui/src/web-components/sketch-view-mode-select.ts
index c6385d3..0264f87 100644
--- a/webui/src/web-components/sketch-view-mode-select.ts
+++ b/webui/src/web-components/sketch-view-mode-select.ts
@@ -1,9 +1,10 @@
-import { css, html, LitElement } from "lit";
+import { html } from "lit";
import { customElement, property } from "lit/decorators.js";
import "./sketch-container-status";
+import { SketchTailwindElement } from "./sketch-tailwind-element";
@customElement("sketch-view-mode-select")
-export class SketchViewModeSelect extends LitElement {
+export class SketchViewModeSelect extends SketchTailwindElement {
// Current active mode
@property()
activeMode: "chat" | "diff2" | "terminal" = "chat";
@@ -17,81 +18,6 @@
// Header bar: view mode buttons
- static styles = css`
- /* Tab-style View Mode Styles */
- .tab-nav {
- display: flex;
- margin-right: 10px;
- background-color: #f8f8f8;
- border-radius: 4px;
- overflow: hidden;
- border: 1px solid #ddd;
- }
-
- .tab-btn {
- padding: 8px 12px;
- background: none;
- border: none;
- cursor: pointer;
- font-size: 13px;
- display: flex;
- align-items: center;
- gap: 5px;
- color: #666;
- border-bottom: 2px solid transparent;
- transition: all 0.2s ease;
- white-space: nowrap;
- }
-
- @media (max-width: 1400px) {
- .tab-btn span:not(.tab-icon):not(.diff-stats) {
- display: none;
- }
-
- .tab-btn {
- padding: 8px 10px;
- }
-
- /* Always show diff stats */
- .diff-stats {
- display: inline !important;
- font-size: 11px;
- margin-left: 2px;
- }
- }
-
- /* Style for diff stats */
- .diff-stats {
- font-size: 11px;
- margin-left: 4px;
- color: inherit;
- opacity: 0.8;
- }
-
- .tab-btn.active .diff-stats {
- opacity: 1;
- }
-
- .tab-btn:not(:last-child) {
- border-right: 1px solid #eee;
- }
-
- .tab-btn:hover {
- background-color: #f0f0f0;
- }
-
- .tab-btn.active {
- border-bottom: 2px solid #4a90e2;
- color: #4a90e2;
- font-weight: 500;
- background-color: #e6f7ff;
- }
-
- .tab-icon {
- font-size: 16px;
- }
- `;
-
constructor() {
super();
@@ -147,29 +73,41 @@
render() {
return html`
- <div class="tab-nav">
+ <div
+ class="flex mr-2.5 bg-gray-100 rounded border border-gray-300 overflow-hidden"
+ >
<button
id="showConversationButton"
- class="tab-btn ${this.activeMode === "chat" ? "active" : ""}"
+ class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 border-transparent transition-all whitespace-nowrap ${this
+ .activeMode === "chat"
+ ? "!border-b-blue-600 text-blue-600 font-medium bg-blue-50"
+ : "hover:bg-gray-200"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 last-of-type:border-r-0"
title="Conversation View"
@click=${() => this._handleViewModeClick("chat")}
>
- <span class="tab-icon">💬</span>
- <span>Chat</span>
+ <span class="tab-icon text-base">💬</span>
+ <span class="max-sm:hidden sm:max-xl:hidden">Chat</span>
</button>
<button
id="showDiff2Button"
- class="tab-btn ${this.activeMode === "diff2" ? "active" : ""}"
+ class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 border-transparent transition-all whitespace-nowrap ${this
+ .activeMode === "diff2"
+ ? "!border-b-blue-600 text-blue-600 font-medium bg-blue-50"
+ : "hover:bg-gray-200"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 last-of-type:border-r-0"
title="Diff View - ${this.diffLinesAdded > 0 ||
this.diffLinesRemoved > 0
? `+${this.diffLinesAdded} -${this.diffLinesRemoved}`
: "No changes"}"
@click=${() => this._handleViewModeClick("diff2")}
>
- <span class="tab-icon">±</span>
- <span class="diff-text">Diff</span>
+ <span class="tab-icon text-base">±</span>
+ <span class="diff-tex max-sm:hidden sm:max-xl:hidden">Diff</span>
${this.diffLinesAdded > 0 || this.diffLinesRemoved > 0
- ? html`<span class="diff-stats"
+ ? html`<span
+ class="diff-stats text-xs ml-1 opacity-80 ${this.activeMode ===
+ "diff2"
+ ? "opacity-100"
+ : ""}"
>+${this.diffLinesAdded} -${this.diffLinesRemoved}</span
>`
: ""}
@@ -177,12 +115,15 @@
<button
id="showTerminalButton"
- class="tab-btn ${this.activeMode === "terminal" ? "active" : ""}"
+ class="px-3 py-2 bg-none border-0 border-b-2 cursor-pointer text-xs flex items-center gap-1.5 text-gray-600 border-transparent transition-all whitespace-nowrap ${this
+ .activeMode === "terminal"
+ ? "!border-b-blue-600 text-blue-600 font-medium bg-blue-50"
+ : "hover:bg-gray-200"} @xl:px-3 @xl:py-2 @max-xl:px-2.5 @max-xl:[&>span:not(.tab-icon):not(.diff-stats)]:hidden @max-xl:[&>.diff-stats]:inline @max-xl:[&>.diff-stats]:text-xs @max-xl:[&>.diff-stats]:ml-0.5 border-r border-gray-200 last-of-type:border-r-0"
title="Terminal View"
@click=${() => this._handleViewModeClick("terminal")}
>
- <span class="tab-icon">💻</span>
- <span>Terminal</span>
+ <span class="tab-icon text-base">💻</span>
+ <span class="max-sm:hidden sm:max-xl:hidden">Terminal</span>
</button>
</div>
`;