refactor(suite): clean up base layout and modularize app scripts

This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-01-25 13:33:03 -03:00
parent fee8b3d2a3
commit 5657e33006
6 changed files with 1473 additions and 2599 deletions

View file

@ -1,192 +0,0 @@
/* =============================================================================
BOTUI SUITE - BASE LAYOUT JAVASCRIPT
Sentient Theme with AI Assistant Panel
============================================================================= */
(function() {
'use strict';
// =============================================================================
// STATE
// =============================================================================
const state = {
aiPanelOpen: true,
currentApp: 'dashboard',
messages: []
};
// =============================================================================
// AI PANEL
// =============================================================================
window.toggleAIPanel = function() {
const panel = document.getElementById('ai-panel');
if (panel) {
panel.classList.toggle('open');
state.aiPanelOpen = panel.classList.contains('open');
}
};
window.sendAIMessage = function() {
const input = document.getElementById('ai-input');
if (!input || !input.value.trim()) return;
const message = input.value.trim();
input.value = '';
addMessage('user', message);
showTypingIndicator();
// Simulate AI response
setTimeout(() => {
hideTypingIndicator();
addMessage('assistant', `Entendido! Vou processar sua solicitação: "${message}"`);
}, 1500);
};
function addMessage(type, content, action) {
const container = document.getElementById('ai-messages');
if (!container) return;
const messageEl = document.createElement('div');
messageEl.className = `ai-message ${type}`;
let html = `<div class="ai-message-bubble">${content}</div>`;
if (action) {
html += `<span class="ai-message-action">${action}</span>`;
}
messageEl.innerHTML = html;
container.appendChild(messageEl);
container.scrollTop = container.scrollHeight;
state.messages.push({ type, content, action });
}
function showTypingIndicator() {
const container = document.getElementById('ai-messages');
if (!container) return;
const indicator = document.createElement('div');
indicator.className = 'ai-message assistant';
indicator.id = 'typing-indicator';
indicator.innerHTML = `
<div class="ai-typing-indicator">
<span></span><span></span><span></span>
</div>
`;
container.appendChild(indicator);
container.scrollTop = container.scrollHeight;
}
function hideTypingIndicator() {
const indicator = document.getElementById('typing-indicator');
if (indicator) indicator.remove();
}
// =============================================================================
// APP LAUNCHER
// =============================================================================
function initAppLauncher() {
document.querySelectorAll('.app-icon').forEach(icon => {
icon.addEventListener('click', function() {
const app = this.dataset.app;
switchApp(app);
});
});
}
function switchApp(appName) {
document.querySelectorAll('.app-icon').forEach(icon => {
icon.classList.toggle('active', icon.dataset.app === appName);
});
state.currentApp = appName;
// Dispatch custom event for app switching
document.dispatchEvent(new CustomEvent('app-switch', { detail: { app: appName } }));
}
// =============================================================================
// NAVIGATION TABS
// =============================================================================
function initTabs() {
document.querySelectorAll('.topbar-tab').forEach(tab => {
tab.addEventListener('click', function() {
document.querySelectorAll('.topbar-tab').forEach(t => t.classList.remove('active'));
this.classList.add('active');
});
});
}
// =============================================================================
// QUICK ACTIONS
// =============================================================================
function initQuickActions() {
document.querySelectorAll('.quick-action-btn').forEach(btn => {
btn.addEventListener('click', function() {
const action = this.textContent;
addMessage('user', action);
showTypingIndicator();
setTimeout(() => {
hideTypingIndicator();
addMessage('assistant', `Ação "${action}" executada com sucesso!`, 'Ver alterações');
}, 1000);
});
});
}
// =============================================================================
// KEYBOARD SHORTCUTS
// =============================================================================
function initKeyboardShortcuts() {
document.addEventListener('keydown', function(e) {
// Enter to send message in AI input
if (e.key === 'Enter' && document.activeElement.id === 'ai-input') {
e.preventDefault();
sendAIMessage();
}
// Escape to close AI panel on mobile
if (e.key === 'Escape' && window.innerWidth <= 1024) {
const panel = document.getElementById('ai-panel');
if (panel && panel.classList.contains('open')) {
toggleAIPanel();
}
}
});
}
// =============================================================================
// INITIAL MESSAGES
// =============================================================================
function loadInitialMessages() {
addMessage('assistant', 'Olá! Sou o AI Developer. Como posso ajudar você hoje?');
addMessage('assistant', 'Você pode me pedir para modificar campos, alterar cores, adicionar validações ou qualquer outra mudança no sistema.');
}
// =============================================================================
// INITIALIZE
// =============================================================================
function init() {
initAppLauncher();
initTabs();
initQuickActions();
initKeyboardShortcuts();
loadInitialMessages();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();

View file

@ -3,49 +3,19 @@
<div class="docs-app" id="docs-app"> <div class="docs-app" id="docs-app">
<div class="docs-toolbar"> <div class="docs-toolbar">
<div class="toolbar-left"> <div class="toolbar-left">
<input <input type="text" class="doc-name-input" id="docName" value="Untitled Document" spellcheck="false" />
type="text"
class="doc-name-input"
id="docName"
value="Untitled Document"
spellcheck="false"
/>
</div> </div>
<div class="toolbar-center"> <div class="toolbar-center">
<div class="toolbar-group"> <div class="toolbar-group">
<button <button class="btn-icon" id="printPreviewBtn" title="Print Preview">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="printPreviewBtn"
title="Print Preview"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polyline points="6 9 6 2 18 2 18 9"></polyline> <polyline points="6 9 6 2 18 2 18 9"></polyline>
<path <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
></path>
<rect x="6" y="14" width="12" height="8"></rect> <rect x="6" y="14" width="12" height="8"></rect>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="findReplaceBtn" title="Find & Replace (Ctrl+H)">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="findReplaceBtn"
title="Find & Replace (Ctrl+H)"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="11" cy="11" r="8"></circle> <circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line> <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg> </svg>
@ -54,42 +24,21 @@
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button class="btn-icon" id="undoBtn" title="Undo (Ctrl+Z)"> <button class="btn-icon" id="undoBtn" title="Undo (Ctrl+Z)">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M3 7v6h6"></path> <path d="M3 7v6h6"></path>
<path <path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"></path>
d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"
></path>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="redoBtn" title="Redo (Ctrl+Y)"> <button class="btn-icon" id="redoBtn" title="Redo (Ctrl+Y)">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M21 7v6h-6"></path> <path d="M21 7v6h-6"></path>
<path <path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13"></path>
d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13"
></path>
</svg> </svg>
</button> </button>
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<select <select class="toolbar-select heading-select" id="headingSelect">
class="toolbar-select heading-select"
id="headingSelect"
>
<option value="p">Normal</option> <option value="p">Normal</option>
<option value="h1">Heading 1</option> <option value="h1">Heading 1</option>
<option value="h2">Heading 2</option> <option value="h2">Heading 2</option>
@ -120,11 +69,7 @@
<button class="btn-icon" id="italicBtn" title="Italic (Ctrl+I)"> <button class="btn-icon" id="italicBtn" title="Italic (Ctrl+I)">
<em>I</em> <em>I</em>
</button> </button>
<button <button class="btn-icon" id="underlineBtn" title="Underline (Ctrl+U)">
class="btn-icon"
id="underlineBtn"
title="Underline (Ctrl+U)"
>
<u>U</u> <u>U</u>
</button> </button>
<button class="btn-icon" id="strikeBtn" title="Strikethrough"> <button class="btn-icon" id="strikeBtn" title="Strikethrough">
@ -133,107 +78,45 @@
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button <button class="btn-icon color-btn" id="textColorBtn" title="Text Color">
class="btn-icon color-btn"
id="textColorBtn"
title="Text Color"
>
<span class="color-letter">A</span> <span class="color-letter">A</span>
<span <span class="color-indicator" id="textColorIndicator"></span>
class="color-indicator" <input type="color" class="color-input" id="textColorInput" value="#000000" />
id="textColorIndicator"
></span>
<input
type="color"
class="color-input"
id="textColorInput"
value="#000000"
/>
</button> </button>
<button <button class="btn-icon color-btn" id="highlightBtn" title="Highlight">
class="btn-icon color-btn" <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
id="highlightBtn"
title="Highlight"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="currentColor"
>
<path <path
d="M15.243 4.515l-6.738 6.737-.707 2.121-1.04 1.041 2.828 2.828 1.04-1.04 2.122-.707 6.737-6.738-4.242-4.242zm6.364 3.536a1 1 0 0 1 0 1.414l-7.778 7.778-2.122.707-1.414 1.414a1 1 0 0 1-1.414 0l-4.243-4.243a1 1 0 0 1 0-1.414l1.414-1.414.707-2.121 7.778-7.778a1 1 0 0 1 1.414 0l5.657 5.657z" d="M15.243 4.515l-6.738 6.737-.707 2.121-1.04 1.041 2.828 2.828 1.04-1.04 2.122-.707 6.737-6.738-4.242-4.242zm6.364 3.536a1 1 0 0 1 0 1.414l-7.778 7.778-2.122.707-1.414 1.414a1 1 0 0 1-1.414 0l-4.243-4.243a1 1 0 0 1 0-1.414l1.414-1.414.707-2.121 7.778-7.778a1 1 0 0 1 1.414 0l5.657 5.657z" />
/>
</svg> </svg>
<span <span class="color-indicator bg-indicator" id="highlightIndicator"></span>
class="color-indicator bg-indicator" <input type="color" class="color-input" id="highlightInput" value="#ffff00" />
id="highlightIndicator"
></span>
<input
type="color"
class="color-input"
id="highlightInput"
value="#ffff00"
/>
</button> </button>
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button class="btn-icon" id="alignLeftBtn" title="Align Left"> <button class="btn-icon" id="alignLeftBtn" title="Align Left">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="12" x2="15" y2="12"></line> <line x1="3" y1="12" x2="15" y2="12"></line>
<line x1="3" y1="18" x2="18" y2="18"></line> <line x1="3" y1="18" x2="18" y2="18"></line>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="alignCenterBtn" title="Align Center">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="alignCenterBtn"
title="Align Center"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="6" y1="12" x2="18" y2="12"></line> <line x1="6" y1="12" x2="18" y2="12"></line>
<line x1="4" y1="18" x2="20" y2="18"></line> <line x1="4" y1="18" x2="20" y2="18"></line>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="alignRightBtn" title="Align Right"> <button class="btn-icon" id="alignRightBtn" title="Align Right">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="9" y1="12" x2="21" y2="12"></line> <line x1="9" y1="12" x2="21" y2="12"></line>
<line x1="6" y1="18" x2="21" y2="18"></line> <line x1="6" y1="18" x2="21" y2="18"></line>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="justifyBtn" title="Justify"> <button class="btn-icon" id="justifyBtn" title="Justify">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="12" x2="21" y2="12"></line> <line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="18" x2="21" y2="18"></line> <line x1="3" y1="18" x2="21" y2="18"></line>
@ -243,110 +126,41 @@
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button class="btn-icon" id="bulletListBtn" title="Bullet List"> <button class="btn-icon" id="bulletListBtn" title="Bullet List">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="9" y1="6" x2="21" y2="6"></line> <line x1="9" y1="6" x2="21" y2="6"></line>
<line x1="9" y1="12" x2="21" y2="12"></line> <line x1="9" y1="12" x2="21" y2="12"></line>
<line x1="9" y1="18" x2="21" y2="18"></line> <line x1="9" y1="18" x2="21" y2="18"></line>
<circle <circle cx="4" cy="6" r="2" fill="currentColor"></circle>
cx="4" <circle cx="4" cy="12" r="2" fill="currentColor"></circle>
cy="6" <circle cx="4" cy="18" r="2" fill="currentColor"></circle>
r="2"
fill="currentColor"
></circle>
<circle
cx="4"
cy="12"
r="2"
fill="currentColor"
></circle>
<circle
cx="4"
cy="18"
r="2"
fill="currentColor"
></circle>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="numberListBtn" title="Numbered List">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="numberListBtn"
title="Numbered List"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="10" y1="6" x2="21" y2="6"></line> <line x1="10" y1="6" x2="21" y2="6"></line>
<line x1="10" y1="12" x2="21" y2="12"></line> <line x1="10" y1="12" x2="21" y2="12"></line>
<line x1="10" y1="18" x2="21" y2="18"></line> <line x1="10" y1="18" x2="21" y2="18"></line>
<text <text x="2" y="8" font-size="8" fill="currentColor" stroke="none">
x="2"
y="8"
font-size="8"
fill="currentColor"
stroke="none"
>
1 1
</text> </text>
<text <text x="2" y="14" font-size="8" fill="currentColor" stroke="none">
x="2"
y="14"
font-size="8"
fill="currentColor"
stroke="none"
>
2 2
</text> </text>
<text <text x="2" y="20" font-size="8" fill="currentColor" stroke="none">
x="2"
y="20"
font-size="8"
fill="currentColor"
stroke="none"
>
3 3
</text> </text>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="indentBtn" title="Increase Indent"> <button class="btn-icon" id="indentBtn" title="Increase Indent">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="9" y1="12" x2="21" y2="12"></line> <line x1="9" y1="12" x2="21" y2="12"></line>
<line x1="9" y1="18" x2="21" y2="18"></line> <line x1="9" y1="18" x2="21" y2="18"></line>
<polyline points="3 10 6 12 3 14"></polyline> <polyline points="3 10 6 12 3 14"></polyline>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="outdentBtn" title="Decrease Indent">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="outdentBtn"
title="Decrease Indent"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="9" y1="12" x2="21" y2="12"></line> <line x1="9" y1="12" x2="21" y2="12"></line>
<line x1="9" y1="18" x2="21" y2="18"></line> <line x1="9" y1="18" x2="21" y2="18"></line>
@ -356,87 +170,33 @@
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button <button class="btn-icon" id="headerFooterBtn" title="Edit Header & Footer">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="headerFooterBtn"
title="Edit Header & Footer"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="3" width="18" height="18" rx="2"></rect> <rect x="3" y="3" width="18" height="18" rx="2"></rect>
<line x1="3" y1="7" x2="21" y2="7"></line> <line x1="3" y1="7" x2="21" y2="7"></line>
<line x1="3" y1="17" x2="21" y2="17"></line> <line x1="3" y1="17" x2="21" y2="17"></line>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="pageBreakBtn" title="Insert Page Break">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="pageBreakBtn"
title="Insert Page Break"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M3 12h4l3-9 4 18 3-9h4"></path> <path d="M3 12h4l3-9 4 18 3-9h4"></path>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="linkBtn" title="Insert Link"> <button class="btn-icon" id="linkBtn" title="Insert Link">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16" <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path>
height="16" <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path
d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"
></path>
<path
d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"
></path>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="imageBtn" title="Insert Image"> <button class="btn-icon" id="imageBtn" title="Insert Image">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16" <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect
x="3"
y="3"
width="18"
height="18"
rx="2"
ry="2"
></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle> <circle cx="8.5" cy="8.5" r="1.5"></circle>
<polyline points="21 15 16 10 5 21"></polyline> <polyline points="21 15 16 10 5 21"></polyline>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="tableBtn" title="Insert Table"> <button class="btn-icon" id="tableBtn" title="Insert Table">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="3" width="18" height="18" rx="2"></rect> <rect x="3" y="3" width="18" height="18" rx="2"></rect>
<line x1="3" y1="9" x2="21" y2="9"></line> <line x1="3" y1="9" x2="21" y2="9"></line>
<line x1="3" y1="15" x2="21" y2="15"></line> <line x1="3" y1="15" x2="21" y2="15"></line>
@ -449,14 +209,7 @@
<div class="toolbar-right"> <div class="toolbar-right">
<div class="collaborators" id="collaborators"></div> <div class="collaborators" id="collaborators"></div>
<button class="btn-primary" id="shareBtn"> <button class="btn-primary" id="shareBtn">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="18" cy="5" r="3"></circle> <circle cx="18" cy="5" r="3"></circle>
<circle cx="6" cy="12" r="3"></circle> <circle cx="6" cy="12" r="3"></circle>
<circle cx="18" cy="19" r="3"></circle> <circle cx="18" cy="19" r="3"></circle>
@ -465,139 +218,19 @@
</svg> </svg>
<span>Share</span> <span>Share</span>
</button> </button>
<button
class="btn-icon chat-toggle"
id="chatToggle"
title="Toggle AI Chat"
>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
></path>
</svg>
</button>
</div> </div>
</div> </div>
<div class="docs-main"> <div class="docs-main">
<div class="docs-canvas"> <div class="docs-canvas">
<div class="editor-page" id="editorPage"> <div class="editor-page" id="editorPage">
<div <div class="editor-content" id="editorContent" contenteditable="true" spellcheck="true"
class="editor-content" data-placeholder="Start typing..."></div>
id="editorContent"
contenteditable="true"
spellcheck="true"
data-placeholder="Start typing..."
></div>
</div> </div>
</div> </div>
<aside class="chat-panel" id="chatPanel">
<div class="chat-header">
<div class="chat-title">
<div class="chat-avatar">
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path
d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z"
/>
<circle cx="12" cy="10" r="3" />
<path
d="M12 15c-3 0-5 1.5-5 3v1h10v-1c0-1.5-2-3-5-3z"
/>
</svg>
</div>
<div>
<h3>AI Assistant</h3>
<span class="chat-status">Ready to help</span>
</div>
</div>
<button class="chat-close" id="chatClose" title="Close">
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
</div>
<div class="chat-messages" id="chatMessages">
<div class="chat-message assistant">
<div class="message-bubble">
<p>
Hi! I can help you edit your document. Try asking me
to:
</p>
<ul>
<li>Make text shorter or longer</li>
<li>Fix grammar and spelling</li>
<li>Translate to another language</li>
<li>Change the tone (formal/casual)</li>
<li>Add a summary</li>
</ul>
</div>
</div>
</div>
<div class="chat-suggestions" id="chatSuggestions">
<button class="suggestion-btn" data-action="shorter">
Make shorter
</button>
<button class="suggestion-btn" data-action="grammar">
Fix grammar
</button>
<button class="suggestion-btn" data-action="formal">
Make formal
</button>
<button class="suggestion-btn" data-action="summarize">
Summarize
</button>
</div>
<form class="chat-input-container" id="chatForm">
<input
type="text"
class="chat-input"
id="chatInput"
placeholder="Ask me to edit your document..."
autocomplete="off"
/>
<button
type="submit"
class="chat-send"
id="chatSend"
title="Send"
>
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="22" y1="2" x2="11" y2="13"></line>
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
</svg>
</button>
</form>
</aside>
</div> </div>
<div class="docs-status-bar"> <div class="docs-status-bar">
@ -628,11 +261,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="share-input-group"> <div class="share-input-group">
<input <input type="email" placeholder="Enter email address" id="shareEmail" />
type="email"
placeholder="Enter email address"
id="shareEmail"
/>
<select id="sharePermission"> <select id="sharePermission">
<option value="view">Can view</option> <option value="view">Can view</option>
<option value="comment">Can comment</option> <option value="comment">Can comment</option>
@ -645,24 +274,10 @@
<div class="share-link-group"> <div class="share-link-group">
<input type="text" readonly id="shareLink" /> <input type="text" readonly id="shareLink" />
<button class="btn-icon" id="copyLinkBtn" title="Copy link"> <button class="btn-icon" id="copyLinkBtn" title="Copy link">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
width="16" stroke-width="2">
height="16" <rect x="9" y="9" width="13" height="13" rx="2"></rect>
viewBox="0 0 24 24" <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect
x="9"
y="9"
width="13"
height="13"
rx="2"
></rect>
<path
d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
></path>
</svg> </svg>
</button> </button>
</div> </div>
@ -680,11 +295,7 @@
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="form-group">
<label>URL</label> <label>URL</label>
<input <input type="url" id="linkUrl" placeholder="https://example.com" />
type="url"
id="linkUrl"
placeholder="https://example.com"
/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Text (optional)</label> <label>Text (optional)</label>
@ -707,19 +318,11 @@
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="form-group">
<label>Image URL</label> <label>Image URL</label>
<input <input type="url" id="imageUrl" placeholder="https://example.com/image.jpg" />
type="url"
id="imageUrl"
placeholder="https://example.com/image.jpg"
/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Alt text</label> <label>Alt text</label>
<input <input type="text" id="imageAlt" placeholder="Image description" />
type="text"
id="imageAlt"
placeholder="Image description"
/>
</div> </div>
<div class="modal-actions"> <div class="modal-actions">
<button class="btn-secondary" id="cancelImageBtn"> <button class="btn-secondary" id="cancelImageBtn">
@ -742,23 +345,11 @@
<div class="form-row"> <div class="form-row">
<div class="form-group"> <div class="form-group">
<label>Rows</label> <label>Rows</label>
<input <input type="number" id="tableRows" value="3" min="1" max="20" />
type="number"
id="tableRows"
value="3"
min="1"
max="20"
/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Columns</label> <label>Columns</label>
<input <input type="number" id="tableCols" value="3" min="1" max="10" />
type="number"
id="tableCols"
value="3"
min="1"
max="10"
/>
</div> </div>
</div> </div>
</div> </div>
@ -782,19 +373,9 @@
<div class="export-options"> <div class="export-options">
<button class="export-option" data-format="pdf"> <button class="export-option" data-format="pdf">
<div class="export-icon"> <div class="export-icon">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
width="24" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
height="24" <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
/>
<polyline points="14 2 14 8 20 8" /> <polyline points="14 2 14 8 20 8" />
<path d="M9 15v-2h1.5a1.5 1.5 0 0 1 0 3H9" /> <path d="M9 15v-2h1.5a1.5 1.5 0 0 1 0 3H9" />
<path d="M13 13h1.5a1.5 1.5 0 0 1 0 3H13v-3z" /> <path d="M13 13h1.5a1.5 1.5 0 0 1 0 3H13v-3z" />
@ -804,19 +385,9 @@
</button> </button>
<button class="export-option" data-format="docx"> <button class="export-option" data-format="docx">
<div class="export-icon"> <div class="export-icon">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
width="24" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
height="24" <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
/>
<polyline points="14 2 14 8 20 8" /> <polyline points="14 2 14 8 20 8" />
<line x1="8" y1="13" x2="16" y2="13" /> <line x1="8" y1="13" x2="16" y2="13" />
<line x1="8" y1="17" x2="14" y2="17" /> <line x1="8" y1="17" x2="14" y2="17" />
@ -826,40 +397,21 @@
</button> </button>
<button class="export-option" data-format="html"> <button class="export-option" data-format="html">
<div class="export-icon"> <div class="export-icon">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
width="24" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="12" cy="12" r="10" /> <circle cx="12" cy="12" r="10" />
<line x1="2" y1="12" x2="22" y2="12" /> <line x1="2" y1="12" x2="22" y2="12" />
<path <path
d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
/>
</svg> </svg>
</div> </div>
<div class="export-label">HTML</div> <div class="export-label">HTML</div>
</button> </button>
<button class="export-option" data-format="txt"> <button class="export-option" data-format="txt">
<div class="export-icon"> <div class="export-icon">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
width="24" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
height="24" <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
/>
<polyline points="14 2 14 8 20 8" /> <polyline points="14 2 14 8 20 8" />
</svg> </svg>
</div> </div>
@ -867,19 +419,9 @@
</button> </button>
<button class="export-option" data-format="md"> <button class="export-option" data-format="md">
<div class="export-icon"> <div class="export-icon">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
width="24" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
height="24" <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
/>
<polyline points="14 2 14 8 20 8" /> <polyline points="14 2 14 8 20 8" />
<path d="M7 15l2-2 2 2" /> <path d="M7 15l2-2 2 2" />
<line x1="9" y1="13" x2="9" y2="17" /> <line x1="9" y1="13" x2="9" y2="17" />
@ -903,20 +445,11 @@
<div class="modal-body"> <div class="modal-body">
<div class="find-replace-group"> <div class="find-replace-group">
<label>Find:</label> <label>Find:</label>
<input <input type="text" id="findInput" placeholder="Search text..." autofocus />
type="text"
id="findInput"
placeholder="Search text..."
autofocus
/>
</div> </div>
<div class="find-replace-group"> <div class="find-replace-group">
<label>Replace:</label> <label>Replace:</label>
<input <input type="text" id="replaceInput" placeholder="Replace with..." />
type="text"
id="replaceInput"
placeholder="Replace with..."
/>
</div> </div>
<div class="find-replace-options"> <div class="find-replace-options">
<label class="checkbox-label"> <label class="checkbox-label">
@ -976,18 +509,9 @@
<div class="modal-actions"> <div class="modal-actions">
<button class="btn-secondary" id="cancelPrintBtn">Cancel</button> <button class="btn-secondary" id="cancelPrintBtn">Cancel</button>
<button class="btn-primary" id="printBtn"> <button class="btn-primary" id="printBtn">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polyline points="6 9 6 2 18 2 18 9"></polyline> <polyline points="6 9 6 2 18 2 18 9"></polyline>
<path <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
></path>
<rect x="6" y="14" width="12" height="8"></rect> <rect x="6" y="14" width="12" height="8"></rect>
</svg> </svg>
Print Print
@ -1010,12 +534,8 @@
<div class="hf-tab-content active" id="hfHeaderTab"> <div class="hf-tab-content active" id="hfHeaderTab">
<div class="form-group"> <div class="form-group">
<label>Header Content:</label> <label>Header Content:</label>
<div <div class="hf-editor" id="headerEditor" contenteditable="true"
class="hf-editor" data-placeholder="Enter header text..."></div>
id="headerEditor"
contenteditable="true"
data-placeholder="Enter header text..."
></div>
</div> </div>
<div class="hf-options"> <div class="hf-options">
<label class="checkbox-label"> <label class="checkbox-label">
@ -1036,10 +556,7 @@
<button class="btn-secondary btn-sm" id="insertDate"> <button class="btn-secondary btn-sm" id="insertDate">
Date Date
</button> </button>
<button <button class="btn-secondary btn-sm" id="insertDocTitle">
class="btn-secondary btn-sm"
id="insertDocTitle"
>
Document Title Document Title
</button> </button>
</div> </div>
@ -1048,12 +565,8 @@
<div class="hf-tab-content" id="hfFooterTab"> <div class="hf-tab-content" id="hfFooterTab">
<div class="form-group"> <div class="form-group">
<label>Footer Content:</label> <label>Footer Content:</label>
<div <div class="hf-editor" id="footerEditor" contenteditable="true"
class="hf-editor" data-placeholder="Enter footer text..."></div>
id="footerEditor"
contenteditable="true"
data-placeholder="Enter footer text..."
></div>
</div> </div>
<div class="hf-options"> <div class="hf-options">
<label class="checkbox-label"> <label class="checkbox-label">
@ -1068,22 +581,13 @@
<div class="hf-insert-options"> <div class="hf-insert-options">
<label>Insert:</label> <label>Insert:</label>
<div class="hf-insert-btns"> <div class="hf-insert-btns">
<button <button class="btn-secondary btn-sm" id="insertFooterPageNum">
class="btn-secondary btn-sm"
id="insertFooterPageNum"
>
Page Number Page Number
</button> </button>
<button <button class="btn-secondary btn-sm" id="insertFooterDate">
class="btn-secondary btn-sm"
id="insertFooterDate"
>
Date Date
</button> </button>
<button <button class="btn-secondary btn-sm" id="insertFooterDocTitle">
class="btn-secondary btn-sm"
id="insertFooterDocTitle"
>
Document Title Document Title
</button> </button>
</div> </div>
@ -1104,4 +608,4 @@
</div> </div>
</div> </div>
<script src="docs/docs.js"></script> <script src="docs/docs.js"></script>

View file

@ -17,7 +17,7 @@
autoSaveTimer: null, autoSaveTimer: null,
ws: null, ws: null,
collaborators: [], collaborators: [],
chatPanelOpen: true,
driveSource: null, driveSource: null,
zoom: 100, zoom: 100,
findMatches: [], findMatches: [],
@ -47,10 +47,7 @@
elements.charCount = document.getElementById("charCount"); elements.charCount = document.getElementById("charCount");
elements.saveStatus = document.getElementById("saveStatus"); elements.saveStatus = document.getElementById("saveStatus");
elements.zoomLevel = document.getElementById("zoomLevel"); elements.zoomLevel = document.getElementById("zoomLevel");
elements.chatPanel = document.getElementById("chatPanel");
elements.chatMessages = document.getElementById("chatMessages");
elements.chatInput = document.getElementById("chatInput");
elements.chatForm = document.getElementById("chatForm");
elements.shareModal = document.getElementById("shareModal"); elements.shareModal = document.getElementById("shareModal");
elements.linkModal = document.getElementById("linkModal"); elements.linkModal = document.getElementById("linkModal");
elements.imageModal = document.getElementById("imageModal"); elements.imageModal = document.getElementById("imageModal");
@ -161,19 +158,7 @@
document.getElementById("zoomInBtn")?.addEventListener("click", zoomIn); document.getElementById("zoomInBtn")?.addEventListener("click", zoomIn);
document.getElementById("zoomOutBtn")?.addEventListener("click", zoomOut); document.getElementById("zoomOutBtn")?.addEventListener("click", zoomOut);
document
.getElementById("chatToggle")
?.addEventListener("click", toggleChatPanel);
document
.getElementById("chatClose")
?.addEventListener("click", toggleChatPanel);
elements.chatForm?.addEventListener("submit", handleChatSubmit);
document.querySelectorAll(".suggestion-btn").forEach((btn) => {
btn.addEventListener("click", () =>
handleSuggestionClick(btn.dataset.action),
);
});
document.querySelectorAll(".btn-close, .modal").forEach((el) => { document.querySelectorAll(".btn-close, .modal").forEach((el) => {
el.addEventListener("click", (e) => { el.addEventListener("click", (e) => {

File diff suppressed because it is too large Load diff

View file

@ -3,82 +3,35 @@
<div class="sheet-app" id="sheet-app"> <div class="sheet-app" id="sheet-app">
<div class="sheet-toolbar"> <div class="sheet-toolbar">
<div class="toolbar-left"> <div class="toolbar-left">
<input <input type="text" class="sheet-name-input" id="sheetName" value="Untitled Spreadsheet"
type="text" spellcheck="false" />
class="sheet-name-input"
id="sheetName"
value="Untitled Spreadsheet"
spellcheck="false"
/>
</div> </div>
<div class="toolbar-center"> <div class="toolbar-center">
<div class="toolbar-group"> <div class="toolbar-group">
<button class="btn-icon" id="undoBtn" title="Undo (Ctrl+Z)"> <button class="btn-icon" id="undoBtn" title="Undo (Ctrl+Z)">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M3 7v6h6"></path> <path d="M3 7v6h6"></path>
<path <path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"></path>
d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"
></path>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="redoBtn" title="Redo (Ctrl+Y)"> <button class="btn-icon" id="redoBtn" title="Redo (Ctrl+Y)">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M21 7v6h-6"></path> <path d="M21 7v6h-6"></path>
<path <path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13"></path>
d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13"
></path>
</svg> </svg>
</button> </button>
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button <button class="btn-icon" id="printPreviewBtn" title="Print Preview">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="printPreviewBtn"
title="Print Preview"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polyline points="6 9 6 2 18 2 18 9"></polyline> <polyline points="6 9 6 2 18 2 18 9"></polyline>
<path <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
></path>
<rect x="6" y="14" width="12" height="8"></rect> <rect x="6" y="14" width="12" height="8"></rect>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="findReplaceBtn" title="Find & Replace (Ctrl+H)">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="findReplaceBtn"
title="Find & Replace (Ctrl+H)"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="11" cy="11" r="8"></circle> <circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line> <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg> </svg>
@ -86,11 +39,7 @@
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<select <select class="toolbar-select font-family" id="fontFamily" title="Font">
class="toolbar-select font-family"
id="fontFamily"
title="Font"
>
<option value="Arial">Arial</option> <option value="Arial">Arial</option>
<option value="Helvetica">Helvetica</option> <option value="Helvetica">Helvetica</option>
<option value="Times New Roman">Times</option> <option value="Times New Roman">Times</option>
@ -98,11 +47,7 @@
<option value="Georgia">Georgia</option> <option value="Georgia">Georgia</option>
<option value="Verdana">Verdana</option> <option value="Verdana">Verdana</option>
</select> </select>
<select <select class="toolbar-select font-size" id="fontSize" title="Size">
class="toolbar-select font-size"
id="fontSize"
title="Size"
>
<option value="8">8</option> <option value="8">8</option>
<option value="9">9</option> <option value="9">9</option>
<option value="10">10</option> <option value="10">10</option>
@ -123,11 +68,7 @@
<button class="btn-icon" id="italicBtn" title="Italic (Ctrl+I)"> <button class="btn-icon" id="italicBtn" title="Italic (Ctrl+I)">
<em>I</em> <em>I</em>
</button> </button>
<button <button class="btn-icon" id="underlineBtn" title="Underline (Ctrl+U)">
class="btn-icon"
id="underlineBtn"
title="Underline (Ctrl+U)"
>
<u>U</u> <u>U</u>
</button> </button>
<button class="btn-icon" id="strikeBtn" title="Strikethrough"> <button class="btn-icon" id="strikeBtn" title="Strikethrough">
@ -136,100 +77,38 @@
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button <button class="btn-icon color-btn" id="textColorBtn" title="Text Color">
class="btn-icon color-btn"
id="textColorBtn"
title="Text Color"
>
<span class="color-letter">A</span> <span class="color-letter">A</span>
<span <span class="color-indicator" id="textColorIndicator"></span>
class="color-indicator" <input type="color" class="color-input" id="textColorInput" value="#000000" />
id="textColorIndicator"
></span>
<input
type="color"
class="color-input"
id="textColorInput"
value="#000000"
/>
</button> </button>
<button <button class="btn-icon color-btn" id="bgColorBtn" title="Fill Color">
class="btn-icon color-btn" <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
id="bgColorBtn" <rect x="3" y="3" width="18" height="18" rx="2" fill="none" stroke="currentColor"
title="Fill Color" stroke-width="2" />
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="currentColor"
>
<rect
x="3"
y="3"
width="18"
height="18"
rx="2"
fill="none"
stroke="currentColor"
stroke-width="2"
/>
</svg> </svg>
<span <span class="color-indicator bg-indicator" id="bgColorIndicator"></span>
class="color-indicator bg-indicator" <input type="color" class="color-input" id="bgColorInput" value="#ffffff" />
id="bgColorIndicator"
></span>
<input
type="color"
class="color-input"
id="bgColorInput"
value="#ffffff"
/>
</button> </button>
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button class="btn-icon" id="alignLeftBtn" title="Align Left"> <button class="btn-icon" id="alignLeftBtn" title="Align Left">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="12" x2="15" y2="12"></line> <line x1="3" y1="12" x2="15" y2="12"></line>
<line x1="3" y1="18" x2="18" y2="18"></line> <line x1="3" y1="18" x2="18" y2="18"></line>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="alignCenterBtn" title="Align Center">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="alignCenterBtn"
title="Align Center"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="6" y1="12" x2="18" y2="12"></line> <line x1="6" y1="12" x2="18" y2="12"></line>
<line x1="4" y1="18" x2="20" y2="18"></line> <line x1="4" y1="18" x2="20" y2="18"></line>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="alignRightBtn" title="Align Right"> <button class="btn-icon" id="alignRightBtn" title="Align Right">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="9" y1="12" x2="21" y2="12"></line> <line x1="9" y1="12" x2="21" y2="12"></line>
<line x1="6" y1="18" x2="21" y2="18"></line> <line x1="6" y1="18" x2="21" y2="18"></line>
@ -238,11 +117,7 @@
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<select <select class="toolbar-select number-format" id="numberFormat" title="Number Format">
class="toolbar-select number-format"
id="numberFormat"
title="Number Format"
>
<option value="general">General</option> <option value="general">General</option>
<option value="number">Number (1,234.56)</option> <option value="number">Number (1,234.56)</option>
<option value="currency">Currency ($1,234.56)</option> <option value="currency">Currency ($1,234.56)</option>
@ -257,38 +132,16 @@
<option value="text">Text</option> <option value="text">Text</option>
<option value="custom">Custom...</option> <option value="custom">Custom...</option>
</select> </select>
<button <button class="btn-icon" id="decreaseDecimalBtn" title="Decrease Decimal">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="decreaseDecimalBtn"
title="Decrease Decimal"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<text x="2" y="16" font-size="10" fill="currentColor"> <text x="2" y="16" font-size="10" fill="currentColor">
.0 .0
</text> </text>
<path d="M18 8l-4 4 4 4"></path> <path d="M18 8l-4 4 4 4"></path>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="increaseDecimalBtn" title="Increase Decimal">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="increaseDecimalBtn"
title="Increase Decimal"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<text x="2" y="16" font-size="10" fill="currentColor"> <text x="2" y="16" font-size="10" fill="currentColor">
.00 .00
</text> </text>
@ -299,165 +152,56 @@
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button class="btn-icon" id="mergeCellsBtn" title="Merge Cells"> <button class="btn-icon" id="mergeCellsBtn" title="Merge Cells">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="3" width="18" height="18" rx="2"></rect> <rect x="3" y="3" width="18" height="18" rx="2"></rect>
<line x1="12" y1="3" x2="12" y2="21"></line> <line x1="12" y1="3" x2="12" y2="21"></line>
<path <path d="M9 12h6M9 12l2-2M9 12l2 2M15 12l-2-2M15 12l-2 2"></path>
d="M9 12h6M9 12l2-2M9 12l2 2M15 12l-2-2M15 12l-2 2"
></path>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="conditionalFormatBtn" title="Conditional Formatting">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="conditionalFormatBtn" <rect x="3" y="3" width="7" height="7" fill="#4CAF50"></rect>
title="Conditional Formatting" <rect x="14" y="3" width="7" height="7" fill="#FFC107"></rect>
> <rect x="3" y="14" width="7" height="7" fill="#F44336"></rect>
<svg <rect x="14" y="14" width="7" height="7" fill="#2196F3"></rect>
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect
x="3"
y="3"
width="7"
height="7"
fill="#4CAF50"
></rect>
<rect
x="14"
y="3"
width="7"
height="7"
fill="#FFC107"
></rect>
<rect
x="3"
y="14"
width="7"
height="7"
fill="#F44336"
></rect>
<rect
x="14"
y="14"
width="7"
height="7"
fill="#2196F3"
></rect>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="dataValidationBtn" title="Data Validation">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="dataValidationBtn"
title="Data Validation"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M9 11l3 3L22 4"></path> <path d="M9 11l3 3L22 4"></path>
<path <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path>
d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"
></path>
</svg> </svg>
</button> </button>
</div> </div>
<span class="toolbar-divider"></span> <span class="toolbar-divider"></span>
<div class="toolbar-group"> <div class="toolbar-group">
<button <button class="btn-icon" id="insertChartBtn" title="Insert Chart">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="insertChartBtn"
title="Insert Chart"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect x="3" y="12" width="4" height="9"></rect> <rect x="3" y="12" width="4" height="9"></rect>
<rect x="10" y="6" width="4" height="15"></rect> <rect x="10" y="6" width="4" height="15"></rect>
<rect x="17" y="3" width="4" height="18"></rect> <rect x="17" y="3" width="4" height="18"></rect>
</svg> </svg>
</button> </button>
<button <button class="btn-icon" id="insertImageBtn" title="Insert Image">
class="btn-icon" <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="insertImageBtn" <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
title="Insert Image"
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect
x="3"
y="3"
width="18"
height="18"
rx="2"
ry="2"
></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle> <circle cx="8.5" cy="8.5" r="1.5"></circle>
<polyline points="21 15 16 10 5 21"></polyline> <polyline points="21 15 16 10 5 21"></polyline>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="filterBtn" title="Filter"> <button class="btn-icon" id="filterBtn" title="Filter">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16" <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon>
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polygon
points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"
></polygon>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="sortAscBtn" title="Sort A→Z"> <button class="btn-icon" id="sortAscBtn" title="Sort A→Z">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M11 5h10M11 9h7M11 13h4"></path> <path d="M11 5h10M11 9h7M11 13h4"></path>
<path d="M3 17l3 3 3-3M6 18V4"></path> <path d="M3 17l3 3 3-3M6 18V4"></path>
</svg> </svg>
</button> </button>
<button class="btn-icon" id="sortDescBtn" title="Sort Z→A"> <button class="btn-icon" id="sortDescBtn" title="Sort Z→A">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M11 5h4M11 9h7M11 13h10"></path> <path d="M11 5h4M11 9h7M11 13h10"></path>
<path d="M3 7l3-3 3 3M6 6v12"></path> <path d="M3 7l3-3 3 3M6 6v12"></path>
</svg> </svg>
@ -467,14 +211,7 @@
<div class="toolbar-right"> <div class="toolbar-right">
<div class="collaborators" id="collaborators"></div> <div class="collaborators" id="collaborators"></div>
<button class="btn-primary" id="shareBtn"> <button class="btn-primary" id="shareBtn">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="18" cy="5" r="3"></circle> <circle cx="18" cy="5" r="3"></circle>
<circle cx="6" cy="12" r="3"></circle> <circle cx="6" cy="12" r="3"></circle>
<circle cx="18" cy="19" r="3"></circle> <circle cx="18" cy="19" r="3"></circle>
@ -483,24 +220,7 @@
</svg> </svg>
<span>Share</span> <span>Share</span>
</button> </button>
<button
class="btn-icon chat-toggle"
id="chatToggle"
title="Toggle AI Chat"
>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
></path>
</svg>
</button>
</div> </div>
</div> </div>
@ -509,12 +229,7 @@
<div class="formula-bar"> <div class="formula-bar">
<div class="cell-address" id="cellAddress">A1</div> <div class="cell-address" id="cellAddress">A1</div>
<span class="formula-icon">fx</span> <span class="formula-icon">fx</span>
<input <input type="text" class="formula-input" id="formulaInput" placeholder="Enter value or formula..." />
type="text"
class="formula-input"
id="formulaInput"
placeholder="Enter value or formula..."
/>
</div> </div>
<div class="sheet-grid-container" id="gridContainer"> <div class="sheet-grid-container" id="gridContainer">
@ -527,18 +242,9 @@
<div class="selection-box" id="selectionBox"></div> <div class="selection-box" id="selectionBox"></div>
<div class="copy-box hidden" id="copyBox"></div> <div class="copy-box hidden" id="copyBox"></div>
<div class="autofill-handle" id="autofillHandle"></div> <div class="autofill-handle" id="autofillHandle"></div>
<div <div class="cursor-indicators" id="cursorIndicators"></div>
class="cursor-indicators" <div class="charts-container" id="chartsContainer"></div>
id="cursorIndicators" <div class="images-container" id="imagesContainer"></div>
></div>
<div
class="charts-container"
id="chartsContainer"
></div>
<div
class="images-container"
id="imagesContainer"
></div>
</div> </div>
</div> </div>
</div> </div>
@ -550,19 +256,8 @@
<button class="tab-menu-btn"></button> <button class="tab-menu-btn"></button>
</div> </div>
</div> </div>
<button <button class="btn-add-sheet" id="addSheetBtn" title="Add Sheet">
class="btn-add-sheet" <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
id="addSheetBtn"
title="Add Sheet"
>
<svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="12" y1="5" x2="12" y2="19"></line> <line x1="12" y1="5" x2="12" y2="19"></line>
<line x1="5" y1="12" x2="19" y2="12"></line> <line x1="5" y1="12" x2="19" y2="12"></line>
</svg> </svg>
@ -587,105 +282,7 @@
</div> </div>
</div> </div>
<aside class="chat-panel" id="chatPanel">
<div class="chat-header">
<div class="chat-title">
<div class="chat-avatar">
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path
d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z"
/>
<circle cx="12" cy="10" r="3" />
<path
d="M12 15c-3 0-5 1.5-5 3v1h10v-1c0-1.5-2-3-5-3z"
/>
</svg>
</div>
<div>
<h3>AI Assistant</h3>
<span class="chat-status">Ready to help</span>
</div>
</div>
<button class="chat-close" id="chatClose" title="Close">
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
</div>
<div class="chat-messages" id="chatMessages">
<div class="chat-message assistant">
<div class="message-bubble">
<p>
Hi! I can help you edit your spreadsheet. Try asking
me to:
</p>
<ul>
<li>Sum a column or range</li>
<li>Format cells as currency</li>
<li>Create a chart</li>
<li>Sort or filter data</li>
<li>Apply conditional formatting</li>
</ul>
</div>
</div>
</div>
<div class="chat-suggestions" id="chatSuggestions">
<button class="suggestion-btn" data-action="sum">
Sum column B
</button>
<button class="suggestion-btn" data-action="format">
Format as $
</button>
<button class="suggestion-btn" data-action="chart">
Create chart
</button>
<button class="suggestion-btn" data-action="sort">
Sort A-Z
</button>
</div>
<form class="chat-input-container" id="chatForm">
<input
type="text"
class="chat-input"
id="chatInput"
placeholder="Ask me to edit your spreadsheet..."
autocomplete="off"
/>
<button
type="submit"
class="chat-send"
id="chatSend"
title="Send"
>
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<line x1="22" y1="2" x2="11" y2="13"></line>
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
</svg>
</button>
</form>
</aside>
</div> </div>
</div> </div>
@ -730,11 +327,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="share-input-group"> <div class="share-input-group">
<input <input type="email" placeholder="Enter email address" id="shareEmail" />
type="email"
placeholder="Enter email address"
id="shareEmail"
/>
<select id="sharePermission"> <select id="sharePermission">
<option value="view">Can view</option> <option value="view">Can view</option>
<option value="edit">Can edit</option> <option value="edit">Can edit</option>
@ -746,25 +339,10 @@
<div class="share-link-group"> <div class="share-link-group">
<input type="text" readonly id="shareLink" /> <input type="text" readonly id="shareLink" />
<button class="btn-icon" id="copyLinkBtn" title="Copy link"> <button class="btn-icon" id="copyLinkBtn" title="Copy link">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
width="16" stroke-width="2">
height="16" <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
viewBox="0 0 24 24" <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
fill="none"
stroke="currentColor"
stroke-width="2"
>
<rect
x="9"
y="9"
width="13"
height="13"
rx="2"
ry="2"
></rect>
<path
d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
></path>
</svg> </svg>
</button> </button>
</div> </div>
@ -782,12 +360,7 @@
<div class="modal-body"> <div class="modal-body">
<div class="chart-type-selector"> <div class="chart-type-selector">
<button class="chart-type-btn active" data-type="bar"> <button class="chart-type-btn active" data-type="bar">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
>
<rect x="3" y="12" width="4" height="9"></rect> <rect x="3" y="12" width="4" height="9"></rect>
<rect x="10" y="6" width="4" height="15"></rect> <rect x="10" y="6" width="4" height="15"></rect>
<rect x="17" y="3" width="4" height="18"></rect> <rect x="17" y="3" width="4" height="18"></rect>
@ -795,27 +368,13 @@
<span>Bar</span> <span>Bar</span>
</button> </button>
<button class="chart-type-btn" data-type="line"> <button class="chart-type-btn" data-type="line">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polyline points="3 18 9 12 13 16 21 6"></polyline> <polyline points="3 18 9 12 13 16 21 6"></polyline>
</svg> </svg>
<span>Line</span> <span>Line</span>
</button> </button>
<button class="chart-type-btn" data-type="pie"> <button class="chart-type-btn" data-type="pie">
<svg <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="12" cy="12" r="10"></circle> <circle cx="12" cy="12" r="10"></circle>
<path d="M12 2v10l8.5 5"></path> <path d="M12 2v10l8.5 5"></path>
</svg> </svg>
@ -824,17 +383,9 @@
</div> </div>
<div class="chart-options"> <div class="chart-options">
<label>Data Range</label> <label>Data Range</label>
<input <input type="text" id="chartDataRange" placeholder="e.g., A1:B10" />
type="text"
id="chartDataRange"
placeholder="e.g., A1:B10"
/>
<label>Chart Title</label> <label>Chart Title</label>
<input <input type="text" id="chartTitle" placeholder="Enter chart title" />
type="text"
id="chartTitle"
placeholder="Enter chart title"
/>
</div> </div>
<div class="modal-actions"> <div class="modal-actions">
<button class="btn-secondary" id="cancelChartBtn"> <button class="btn-secondary" id="cancelChartBtn">
@ -857,20 +408,11 @@
<div class="modal-body"> <div class="modal-body">
<div class="find-replace-group"> <div class="find-replace-group">
<label>Find:</label> <label>Find:</label>
<input <input type="text" id="findInput" placeholder="Search text..." autofocus />
type="text"
id="findInput"
placeholder="Search text..."
autofocus
/>
</div> </div>
<div class="find-replace-group"> <div class="find-replace-group">
<label>Replace:</label> <label>Replace:</label>
<input <input type="text" id="replaceInput" placeholder="Replace with..." />
type="text"
id="replaceInput"
placeholder="Replace with..."
/>
</div> </div>
<div class="find-replace-options"> <div class="find-replace-options">
<label class="checkbox-label"> <label class="checkbox-label">
@ -939,12 +481,7 @@
</div> </div>
<div class="cf-section cf-values" id="cfValuesSection"> <div class="cf-section cf-values" id="cfValuesSection">
<input type="text" id="cfValue1" placeholder="Value" /> <input type="text" id="cfValue1" placeholder="Value" />
<input <input type="text" id="cfValue2" placeholder="and" class="hidden" />
type="text"
id="cfValue2"
placeholder="and"
class="hidden"
/>
</div> </div>
<div class="cf-section"> <div class="cf-section">
<label>Formatting style:</label> <label>Formatting style:</label>
@ -996,11 +533,7 @@
<div class="dv-tab-content active" id="dvSettingsTab"> <div class="dv-tab-content active" id="dvSettingsTab">
<div class="dv-section"> <div class="dv-section">
<label>Apply to range:</label> <label>Apply to range:</label>
<input <input type="text" id="dvRange" placeholder="e.g., A1:A100" />
type="text"
id="dvRange"
placeholder="e.g., A1:A100"
/>
</div> </div>
<div class="dv-section"> <div class="dv-section">
<label>Allow:</label> <label>Allow:</label>
@ -1044,10 +577,7 @@
</div> </div>
<div class="dv-section dv-list hidden" id="dvListSection"> <div class="dv-section dv-list hidden" id="dvListSection">
<label>Source (comma-separated):</label> <label>Source (comma-separated):</label>
<textarea <textarea id="dvListSource" placeholder="Option 1, Option 2, Option 3"></textarea>
id="dvListSource"
placeholder="Option 1, Option 2, Option 3"
></textarea>
</div> </div>
<div class="dv-section"> <div class="dv-section">
<label class="checkbox-label"> <label class="checkbox-label">
@ -1069,18 +599,11 @@
</div> </div>
<div class="dv-section"> <div class="dv-section">
<label>Title:</label> <label>Title:</label>
<input <input type="text" id="dvInputTitle" placeholder="Input title" />
type="text"
id="dvInputTitle"
placeholder="Input title"
/>
</div> </div>
<div class="dv-section"> <div class="dv-section">
<label>Input message:</label> <label>Input message:</label>
<textarea <textarea id="dvInputMessage" placeholder="Enter instructions for the user"></textarea>
id="dvInputMessage"
placeholder="Enter instructions for the user"
></textarea>
</div> </div>
</div> </div>
<div class="dv-tab-content" id="dvErrorTab"> <div class="dv-tab-content" id="dvErrorTab">
@ -1100,18 +623,11 @@
</div> </div>
<div class="dv-section"> <div class="dv-section">
<label>Title:</label> <label>Title:</label>
<input <input type="text" id="dvErrorTitle" placeholder="Error title" />
type="text"
id="dvErrorTitle"
placeholder="Error title"
/>
</div> </div>
<div class="dv-section"> <div class="dv-section">
<label>Error message:</label> <label>Error message:</label>
<textarea <textarea id="dvErrorMessage" placeholder="Enter error message"></textarea>
id="dvErrorMessage"
placeholder="Enter error message"
></textarea>
</div> </div>
</div> </div>
<div class="modal-actions"> <div class="modal-actions">
@ -1166,18 +682,9 @@
<div class="modal-actions"> <div class="modal-actions">
<button class="btn-secondary" id="cancelPrintBtn">Cancel</button> <button class="btn-secondary" id="cancelPrintBtn">Cancel</button>
<button class="btn-primary" id="printBtn"> <button class="btn-primary" id="printBtn">
<svg <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<polyline points="6 9 6 2 18 2 18 9"></polyline> <polyline points="6 9 6 2 18 2 18 9"></polyline>
<path <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
></path>
<rect x="6" y="14" width="12" height="8"></rect> <rect x="6" y="14" width="12" height="8"></rect>
</svg> </svg>
Print Print
@ -1274,22 +781,8 @@
<input type="file" id="imgFile" accept="image/*" /> <input type="file" id="imgFile" accept="image/*" />
</div> </div>
<div class="img-drop-zone" id="imgDropZone"> <div class="img-drop-zone" id="imgDropZone">
<svg <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
width="48" <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
height="48"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1"
>
<rect
x="3"
y="3"
width="18"
height="18"
rx="2"
ry="2"
></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle> <circle cx="8.5" cy="8.5" r="1.5"></circle>
<polyline points="21 15 16 10 5 21"></polyline> <polyline points="21 15 16 10 5 21"></polyline>
</svg> </svg>
@ -1308,4 +801,4 @@
</div> </div>
</div> </div>
<script src="sheet/sheet.js"></script> <script src="sheet/sheet.js"></script>

View file

@ -36,7 +36,7 @@
isSelecting: false, isSelecting: false,
isDirty: false, isDirty: false,
autoSaveTimer: null, autoSaveTimer: null,
chatPanelOpen: true,
findMatches: [], findMatches: [],
findMatchIndex: -1, findMatchIndex: -1,
decimalPlaces: 2, decimalPlaces: 2,
@ -50,7 +50,7 @@
bindEvents(); bindEvents();
loadFromUrlParams(); loadFromUrlParams();
connectWebSocket(); connectWebSocket();
connectChatWebSocket();
selectCell(0, 0); selectCell(0, 0);
updateCellAddress(); updateCellAddress();
renderCharts(); renderCharts();
@ -77,10 +77,7 @@
elements.calculationResult = document.getElementById("calculationResult"); elements.calculationResult = document.getElementById("calculationResult");
elements.saveStatus = document.getElementById("saveStatus"); elements.saveStatus = document.getElementById("saveStatus");
elements.zoomLevel = document.getElementById("zoomLevel"); elements.zoomLevel = document.getElementById("zoomLevel");
elements.chatPanel = document.getElementById("chatPanel");
elements.chatMessages = document.getElementById("chatMessages");
elements.chatInput = document.getElementById("chatInput");
elements.chatForm = document.getElementById("chatForm");
elements.findReplaceModal = document.getElementById("findReplaceModal"); elements.findReplaceModal = document.getElementById("findReplaceModal");
elements.conditionalFormatModal = document.getElementById( elements.conditionalFormatModal = document.getElementById(
"conditionalFormatModal", "conditionalFormatModal",
@ -453,19 +450,7 @@
.getElementById("cnfFormatCode") .getElementById("cnfFormatCode")
?.addEventListener("input", updateCnfPreview); ?.addEventListener("input", updateCnfPreview);
document
.getElementById("chatToggle")
?.addEventListener("click", toggleChatPanel);
document
.getElementById("chatClose")
?.addEventListener("click", toggleChatPanel);
elements.chatForm?.addEventListener("submit", handleChatSubmit);
document.querySelectorAll(".suggestion-btn").forEach((btn) => {
btn.addEventListener("click", () =>
handleSuggestionClick(btn.dataset.action),
);
});
document.querySelectorAll(".context-item").forEach((item) => { document.querySelectorAll(".context-item").forEach((item) => {
item.addEventListener("click", () => item.addEventListener("click", () =>
@ -1970,18 +1955,18 @@
return isNaN(d2.getTime()) return isNaN(d2.getTime())
? value ? value
: d2.toLocaleDateString("en-US", { : d2.toLocaleDateString("en-US", {
year: "numeric", year: "numeric",
month: "long", month: "long",
day: "numeric", day: "numeric",
}); });
case "time": case "time":
const d3 = new Date(num); const d3 = new Date(num);
return isNaN(d3.getTime()) return isNaN(d3.getTime())
? value ? value
: d3.toLocaleTimeString("en-US", { : d3.toLocaleTimeString("en-US", {
hour: "numeric", hour: "numeric",
minute: "2-digit", minute: "2-digit",
}); });
case "datetime": case "datetime":
const d4 = new Date(num); const d4 = new Date(num);
return isNaN(d4.getTime()) ? value : d4.toLocaleString("en-US"); return isNaN(d4.getTime()) ? value : d4.toLocaleString("en-US");