blob: c6385d3f9ca224067be0d170aa6b58e0ddcb5391 [file] [log] [blame]
Sean McCullough71941bd2025-04-18 13:31:48 -07001import { css, html, LitElement } from "lit";
Sean McCulloughd9f13372025-04-21 15:08:49 -07002import { customElement, property } from "lit/decorators.js";
Sean McCullough71941bd2025-04-18 13:31:48 -07003import "./sketch-container-status";
Sean McCullough86b56862025-04-18 13:04:03 -07004
Sean McCullough71941bd2025-04-18 13:31:48 -07005@customElement("sketch-view-mode-select")
Sean McCullough86b56862025-04-18 13:04:03 -07006export class SketchViewModeSelect extends LitElement {
7 // Current active mode
8 @property()
Philip Zeyliger00bcaef2025-05-30 04:21:15 +00009 activeMode: "chat" | "diff2" | "terminal" = "chat";
Philip Zeyliger64f60462025-06-16 13:57:10 -070010
11 // Diff stats
12 @property({ type: Number })
13 diffLinesAdded: number = 0;
14
15 @property({ type: Number })
16 diffLinesRemoved: number = 0;
17
Sean McCullough86b56862025-04-18 13:04:03 -070018 // Header bar: view mode buttons
19
Sean McCullough86b56862025-04-18 13:04:03 -070020 static styles = css`
Philip Zeyligere66db3e2025-04-27 15:40:39 +000021 /* Tab-style View Mode Styles */
22 .tab-nav {
Sean McCullough71941bd2025-04-18 13:31:48 -070023 display: flex;
Sean McCullough71941bd2025-04-18 13:31:48 -070024 margin-right: 10px;
Philip Zeyligere66db3e2025-04-27 15:40:39 +000025 background-color: #f8f8f8;
26 border-radius: 4px;
27 overflow: hidden;
28 border: 1px solid #ddd;
Sean McCullough71941bd2025-04-18 13:31:48 -070029 }
Sean McCullough86b56862025-04-18 13:04:03 -070030
Philip Zeyligere66db3e2025-04-27 15:40:39 +000031 .tab-btn {
32 padding: 8px 12px;
33 background: none;
34 border: none;
35 cursor: pointer;
36 font-size: 13px;
Sean McCullough71941bd2025-04-18 13:31:48 -070037 display: flex;
38 align-items: center;
Philip Zeyligere66db3e2025-04-27 15:40:39 +000039 gap: 5px;
40 color: #666;
41 border-bottom: 2px solid transparent;
Sean McCullough71941bd2025-04-18 13:31:48 -070042 transition: all 0.2s ease;
Philip Zeyligere66db3e2025-04-27 15:40:39 +000043 white-space: nowrap;
Sean McCullough71941bd2025-04-18 13:31:48 -070044 }
Sean McCullough86b56862025-04-18 13:04:03 -070045
Philip Zeyligerbce3a132025-04-30 22:03:39 +000046 @media (max-width: 1400px) {
Philip Zeyliger64f60462025-06-16 13:57:10 -070047 .tab-btn span:not(.tab-icon):not(.diff-stats) {
Philip Zeyligerbce3a132025-04-30 22:03:39 +000048 display: none;
49 }
50
51 .tab-btn {
52 padding: 8px 10px;
53 }
Philip Zeyliger64f60462025-06-16 13:57:10 -070054
55 /* Always show diff stats */
56 .diff-stats {
57 display: inline !important;
58 font-size: 11px;
59 margin-left: 2px;
60 }
61 }
62
63 /* Style for diff stats */
64 .diff-stats {
65 font-size: 11px;
66 margin-left: 4px;
67 color: inherit;
68 opacity: 0.8;
69 }
70
71 .tab-btn.active .diff-stats {
72 opacity: 1;
Philip Zeyligerbce3a132025-04-30 22:03:39 +000073 }
74
Philip Zeyligere66db3e2025-04-27 15:40:39 +000075 .tab-btn:not(:last-child) {
76 border-right: 1px solid #eee;
77 }
78
79 .tab-btn:hover {
Sean McCullough71941bd2025-04-18 13:31:48 -070080 background-color: #f0f0f0;
Sean McCullough71941bd2025-04-18 13:31:48 -070081 }
Sean McCullough86b56862025-04-18 13:04:03 -070082
Philip Zeyligere66db3e2025-04-27 15:40:39 +000083 .tab-btn.active {
84 border-bottom: 2px solid #4a90e2;
85 color: #4a90e2;
86 font-weight: 500;
Sean McCullough71941bd2025-04-18 13:31:48 -070087 background-color: #e6f7ff;
Philip Zeyligere66db3e2025-04-27 15:40:39 +000088 }
89
90 .tab-icon {
91 font-size: 16px;
Sean McCullough71941bd2025-04-18 13:31:48 -070092 }
93 `;
94
Sean McCullough86b56862025-04-18 13:04:03 -070095 constructor() {
96 super();
Sean McCullough71941bd2025-04-18 13:31:48 -070097
Sean McCullough86b56862025-04-18 13:04:03 -070098 // Binding methods
99 this._handleViewModeClick = this._handleViewModeClick.bind(this);
100 this._handleUpdateActiveMode = this._handleUpdateActiveMode.bind(this);
101 }
102
103 // See https://lit.dev/docs/components/lifecycle/
104 connectedCallback() {
105 super.connectedCallback();
Sean McCullough71941bd2025-04-18 13:31:48 -0700106
Sean McCullough86b56862025-04-18 13:04:03 -0700107 // Listen for update-active-mode events
Sean McCullough71941bd2025-04-18 13:31:48 -0700108 this.addEventListener(
109 "update-active-mode",
110 this._handleUpdateActiveMode as EventListener,
111 );
Sean McCullough86b56862025-04-18 13:04:03 -0700112 }
Sean McCullough71941bd2025-04-18 13:31:48 -0700113
Sean McCullough86b56862025-04-18 13:04:03 -0700114 /**
115 * Handle view mode button clicks
116 */
Philip Zeyliger00bcaef2025-05-30 04:21:15 +0000117 private _handleViewModeClick(mode: "chat" | "diff2" | "terminal") {
Sean McCullough86b56862025-04-18 13:04:03 -0700118 // Dispatch a custom event to notify the app shell to change the view
Sean McCullough71941bd2025-04-18 13:31:48 -0700119 const event = new CustomEvent("view-mode-select", {
Sean McCullough86b56862025-04-18 13:04:03 -0700120 detail: { mode },
121 bubbles: true,
Sean McCullough71941bd2025-04-18 13:31:48 -0700122 composed: true,
Sean McCullough86b56862025-04-18 13:04:03 -0700123 });
124 this.dispatchEvent(event);
125 }
Sean McCullough71941bd2025-04-18 13:31:48 -0700126
Sean McCullough86b56862025-04-18 13:04:03 -0700127 /**
128 * Handle updates to the active mode
129 */
130 private _handleUpdateActiveMode(event: CustomEvent) {
131 const { mode } = event.detail;
132 if (mode) {
133 this.activeMode = mode;
134 }
135 }
136
137 // See https://lit.dev/docs/components/lifecycle/
138 disconnectedCallback() {
139 super.disconnectedCallback();
Sean McCullough71941bd2025-04-18 13:31:48 -0700140
Sean McCullough86b56862025-04-18 13:04:03 -0700141 // Remove event listeners
Sean McCullough71941bd2025-04-18 13:31:48 -0700142 this.removeEventListener(
143 "update-active-mode",
144 this._handleUpdateActiveMode as EventListener,
145 );
Sean McCullough86b56862025-04-18 13:04:03 -0700146 }
147
148 render() {
149 return html`
Philip Zeyligere66db3e2025-04-27 15:40:39 +0000150 <div class="tab-nav">
Sean McCullough86b56862025-04-18 13:04:03 -0700151 <button
152 id="showConversationButton"
Philip Zeyligere66db3e2025-04-27 15:40:39 +0000153 class="tab-btn ${this.activeMode === "chat" ? "active" : ""}"
Sean McCullough86b56862025-04-18 13:04:03 -0700154 title="Conversation View"
Sean McCullough71941bd2025-04-18 13:31:48 -0700155 @click=${() => this._handleViewModeClick("chat")}
Sean McCullough86b56862025-04-18 13:04:03 -0700156 >
Philip Zeyligere66db3e2025-04-27 15:40:39 +0000157 <span class="tab-icon">💬</span>
158 <span>Chat</span>
Sean McCullough86b56862025-04-18 13:04:03 -0700159 </button>
160 <button
Philip Zeyliger272a90e2025-05-16 14:49:51 -0700161 id="showDiff2Button"
162 class="tab-btn ${this.activeMode === "diff2" ? "active" : ""}"
Philip Zeyliger64f60462025-06-16 13:57:10 -0700163 title="Diff View - ${this.diffLinesAdded > 0 ||
164 this.diffLinesRemoved > 0
165 ? `+${this.diffLinesAdded} -${this.diffLinesRemoved}`
166 : "No changes"}"
Philip Zeyliger272a90e2025-05-16 14:49:51 -0700167 @click=${() => this._handleViewModeClick("diff2")}
Sean McCullough86b56862025-04-18 13:04:03 -0700168 >
Philip Zeyligere66db3e2025-04-27 15:40:39 +0000169 <span class="tab-icon">±</span>
Philip Zeyliger64f60462025-06-16 13:57:10 -0700170 <span class="diff-text">Diff</span>
171 ${this.diffLinesAdded > 0 || this.diffLinesRemoved > 0
172 ? html`<span class="diff-stats"
173 >+${this.diffLinesAdded} -${this.diffLinesRemoved}</span
174 >`
175 : ""}
Sean McCullough86b56862025-04-18 13:04:03 -0700176 </button>
Autoformatter8c463622025-05-16 21:54:17 +0000177
Sean McCullough86b56862025-04-18 13:04:03 -0700178 <button
179 id="showTerminalButton"
Philip Zeyligere66db3e2025-04-27 15:40:39 +0000180 class="tab-btn ${this.activeMode === "terminal" ? "active" : ""}"
Sean McCullough86b56862025-04-18 13:04:03 -0700181 title="Terminal View"
Sean McCullough71941bd2025-04-18 13:31:48 -0700182 @click=${() => this._handleViewModeClick("terminal")}
Sean McCullough86b56862025-04-18 13:04:03 -0700183 >
Philip Zeyligere66db3e2025-04-27 15:40:39 +0000184 <span class="tab-icon">💻</span>
185 <span>Terminal</span>
Sean McCullough86b56862025-04-18 13:04:03 -0700186 </button>
187 </div>
188 `;
189 }
190}
191
192declare global {
193 interface HTMLElementTagNameMap {
194 "sketch-view-mode-select": SketchViewModeSelect;
195 }
Sean McCullough71941bd2025-04-18 13:31:48 -0700196}