Calculator UI Fix
This commit is contained in:
@@ -145,12 +145,31 @@ const CalculatorPopover: Component = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePaste = (e: ClipboardEvent) => {
|
||||||
|
if (!isOpen()) return;
|
||||||
|
|
||||||
|
// Don't intercept if an input is focused
|
||||||
|
const activeElement = document.activeElement;
|
||||||
|
const isInputFocused = activeElement instanceof HTMLInputElement ||
|
||||||
|
activeElement instanceof HTMLTextAreaElement ||
|
||||||
|
activeElement?.hasAttribute('contenteditable');
|
||||||
|
|
||||||
|
if (isInputFocused) return;
|
||||||
|
|
||||||
|
const pastedText = e.clipboardData?.getData('text/plain');
|
||||||
|
if (pastedText && !isNaN(parseFloat(pastedText))) {
|
||||||
|
addValue(parseFloat(pastedText), 'Pasted Value');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
window.addEventListener('keydown', handleKeyDown);
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
window.addEventListener('paste', handlePaste);
|
||||||
});
|
});
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
window.removeEventListener('keydown', handleKeyDown);
|
window.removeEventListener('keydown', handleKeyDown);
|
||||||
|
window.removeEventListener('paste', handlePaste);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -182,19 +201,19 @@ const CalculatorPopover: Component = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Display */}
|
{/* Display */}
|
||||||
<div class="p-8 bg-foreground text-background min-h-[220px] flex flex-col justify-end items-end relative overflow-hidden group/display">
|
<div class="p-8 bg-muted text-foreground min-h-[220px] flex flex-col justify-end items-end relative overflow-hidden group/display border-b border-border">
|
||||||
<div class="absolute top-6 left-8 text-[10px] font-black text-background/30 uppercase tracking-[0.3em]">Calculation History</div>
|
<div class="absolute top-6 left-8 text-[10px] font-black text-muted-foreground/30 uppercase tracking-[0.3em]">Calculation History</div>
|
||||||
|
|
||||||
<div class="flex flex-col items-end gap-2 mb-4 max-h-56 overflow-y-auto w-full custom-scrollbar pr-2 scroll-smooth">
|
<div class="flex flex-col items-end gap-2 mb-4 max-h-56 overflow-y-auto w-full custom-scrollbar pr-2 scroll-smooth">
|
||||||
<For each={entries()}>
|
<For each={entries()}>
|
||||||
{(entry) => (
|
{(entry) => (
|
||||||
<Show when={entry.type === 'marker'} fallback={
|
<Show when={entry.type === 'marker'} fallback={
|
||||||
<div class={`flex items-center gap-3 group/entry transition-all ${entry.type === 'result' ? 'mt-3 pt-3 border-t border-background/10 w-full justify-end' : ''}`}>
|
<div class={`flex items-center gap-3 group/entry transition-all ${entry.type === 'result' ? 'mt-3 pt-3 border-t border-border w-full justify-end' : ''}`}>
|
||||||
<Show when={entry.label}>
|
<Show when={entry.label}>
|
||||||
<span class="text-[9px] font-black text-background/40 uppercase tracking-wider truncate max-w-[200px] group-hover/entry:text-background/60 transition-colors">{entry.label}</span>
|
<span class="text-[9px] font-black text-muted-foreground/40 uppercase tracking-wider truncate max-w-[200px] group-hover/entry:text-muted-foreground/60 transition-colors">{entry.label}</span>
|
||||||
</Show>
|
</Show>
|
||||||
<div class={`px-3 py-1 rounded-xl text-xs font-black shadow-sm transition-transform group-hover/entry:scale-105 ${entry.type === 'field' ? 'bg-primary text-primary-foreground shadow-primary/20' :
|
<div class={`px-3 py-1 rounded-xl text-xs font-black shadow-sm transition-transform group-hover/entry:scale-105 ${entry.type === 'field' ? 'bg-primary text-primary-foreground shadow-primary/20' :
|
||||||
entry.type === 'result' ? 'bg-primary/20 text-primary border border-primary/30' : 'bg-background/10 text-background/80'
|
entry.type === 'result' ? 'bg-primary/20 text-primary border border-primary/30' : 'bg-background text-foreground/80 border border-border/60'
|
||||||
}`}>
|
}`}>
|
||||||
{entry.type === 'result' && <span class="mr-2 opacity-60">=</span>}
|
{entry.type === 'result' && <span class="mr-2 opacity-60">=</span>}
|
||||||
{formatNumber(entry.value || 0)}
|
{formatNumber(entry.value || 0)}
|
||||||
@@ -202,11 +221,11 @@ const CalculatorPopover: Component = () => {
|
|||||||
</div>
|
</div>
|
||||||
}>
|
}>
|
||||||
<div class="w-full flex items-center gap-4 my-4 opacity-50">
|
<div class="w-full flex items-center gap-4 my-4 opacity-50">
|
||||||
<div class="h-px flex-1 bg-gradient-to-r from-transparent to-background/20"></div>
|
<div class="h-px flex-1 bg-gradient-to-r from-transparent to-border"></div>
|
||||||
<span class="text-[9px] font-black text-background/60 uppercase tracking-[0.2em] whitespace-nowrap bg-background/5 px-3 py-1 rounded-full border border-background/10 italic">
|
<span class="text-[9px] font-black text-muted-foreground/60 uppercase tracking-[0.2em] whitespace-nowrap bg-muted px-3 py-1 rounded-full border border-border italic">
|
||||||
{entry.label}
|
{entry.label}
|
||||||
</span>
|
</span>
|
||||||
<div class="h-px flex-1 bg-gradient-to-l from-transparent to-background/20"></div>
|
<div class="h-px flex-1 bg-gradient-to-l from-transparent to-border"></div>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
)}
|
)}
|
||||||
@@ -259,18 +278,20 @@ const CalculatorPopover: Component = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<button
|
<div class="group relative flex items-center">
|
||||||
onClick={() => setIsOpen(!isOpen())}
|
|
||||||
class={`p-5 rounded-full shadow-elevated transition-all duration-500 group relative border-2 ${isOpen() ? 'bg-foreground text-background border-foreground rotate-90 scale-110' : 'bg-primary text-primary-foreground border-primary shadow-primary/20 hover:scale-110 hover:shadow-2xl'}`}
|
|
||||||
>
|
|
||||||
{isOpen() ? <X class="w-6 h-6" /> : <Calculator class="w-6 h-6" />}
|
|
||||||
<Show when={!isOpen()}>
|
<Show when={!isOpen()}>
|
||||||
<span class="absolute right-full mr-6 px-4 py-2 bg-foreground text-background text-[10px] font-black uppercase tracking-widest rounded-xl opacity-0 group-hover:opacity-100 transition-all translate-x-4 group-hover:translate-x-0 pointer-events-none shadow-2xl flex items-center gap-2">
|
<span class="absolute right-full mr-6 px-4 py-2 bg-foreground text-background text-[10px] font-black uppercase tracking-widest rounded-xl opacity-0 group-hover:opacity-100 transition-all translate-x-4 group-hover:translate-x-0 pointer-events-none shadow-2xl flex items-center gap-2">
|
||||||
<Calculator class="w-3 h-3 text-primary" /> Calculator
|
<Calculator class="w-3 h-3 text-primary" /> Calculator
|
||||||
</span>
|
</span>
|
||||||
</Show>
|
</Show>
|
||||||
|
<button
|
||||||
|
onClick={() => setIsOpen(!isOpen())}
|
||||||
|
class={`p-5 rounded-full shadow-elevated transition-all duration-500 relative border-2 ${isOpen() ? 'bg-foreground text-background border-foreground rotate-90 scale-110' : 'bg-primary text-primary-foreground border-primary shadow-primary/20 hover:scale-110 hover:shadow-2xl'}`}
|
||||||
|
>
|
||||||
|
{isOpen() ? <X class="w-6 h-6" /> : <Calculator class="w-6 h-6" />}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</Portal>
|
</Portal>
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user