more fixes for pad editor, mainly for mobile
This commit is contained in:
@@ -21,8 +21,25 @@
|
||||
let currentWord = $state('');
|
||||
let selectedIndex = $state(-1);
|
||||
let cursorPosition = $state({ x: 0, y: 0 });
|
||||
let isMobile = $state(false);
|
||||
const debounce = createDebounce();
|
||||
|
||||
// Check for mobile on component mount and resize
|
||||
function checkMobile() {
|
||||
isMobile = window.innerWidth < 768;
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
// Add resize listener for responsive behavior
|
||||
window.addEventListener('resize', checkMobile);
|
||||
checkMobile();
|
||||
|
||||
// Cleanup on unmount
|
||||
return () => {
|
||||
window.removeEventListener('resize', checkMobile);
|
||||
};
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (editor?.getHTML()) {
|
||||
localStorage.setItem('tipex', editor.getHTML());
|
||||
@@ -49,7 +66,7 @@
|
||||
currentWord = '';
|
||||
}
|
||||
updateCursorPosition();
|
||||
}, 300);
|
||||
}, 1000);
|
||||
|
||||
const handleSelectionChange = debounce(async () => {
|
||||
const selection = editor?.view.state.selection;
|
||||
@@ -63,6 +80,15 @@
|
||||
}
|
||||
}, 300);
|
||||
|
||||
// Special handler for touch events
|
||||
function handleTouchEnd(event: TouchEvent) {
|
||||
// Prevent default only if we have suggestions
|
||||
if (suggestions.length > 0 || rhymes.length > 0) {
|
||||
event.preventDefault();
|
||||
}
|
||||
handleSelectionChange();
|
||||
}
|
||||
|
||||
function clearSuggestions() {
|
||||
suggestions = [];
|
||||
rhymes = [];
|
||||
@@ -129,7 +155,7 @@
|
||||
<div
|
||||
class="container mx-auto my-8 dark relative px-4"
|
||||
onmouseup={handleSelectionChange}
|
||||
ontouchend={handleSelectionChange}
|
||||
ontouchend={handleTouchEnd}
|
||||
onmousedown={clearSuggestions}
|
||||
ontouchstart={clearSuggestions}
|
||||
role="textbox"
|
||||
@@ -144,7 +170,7 @@
|
||||
|
||||
{#if suggestions.length > 0 || rhymes.length > 0}
|
||||
<div
|
||||
class="suggestions-container"
|
||||
class="suggestions-container {isMobile ? 'mobile-suggestions' : ''}"
|
||||
role="listbox"
|
||||
aria-label="Suggestions and rhymes"
|
||||
style:left="{cursorPosition.x}px"
|
||||
@@ -184,5 +210,30 @@
|
||||
box-shadow:
|
||||
0 4px 6px -1px rgb(0 0 0 / 0.1),
|
||||
0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
touch-action: manipulation;
|
||||
background-color: white;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
/* Mobile-specific styles */
|
||||
.mobile-suggestions {
|
||||
max-width: 90vw;
|
||||
width: 90vw;
|
||||
max-height: 200px;
|
||||
left: 50% !important; /* Override inline styles */
|
||||
bottom: 20px !important;
|
||||
top: auto !important;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.suggestions-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 50% !important;
|
||||
transform: translateX(-50%);
|
||||
top: auto !important;
|
||||
width: 90vw;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -10,6 +10,13 @@
|
||||
selectedIndex: number;
|
||||
onSelect: (word: string) => void;
|
||||
}>();
|
||||
|
||||
const isMobile = window.innerWidth < 768;
|
||||
|
||||
function handleTouchSelect(event: TouchEvent, word: string) {
|
||||
event.preventDefault();
|
||||
onSelect(word);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="bg-white dark:bg-gray-800 shadow-lg rounded-md p-2 mb-2">
|
||||
@@ -17,13 +24,28 @@
|
||||
{#each suggestions.slice(0, 10) as { word }, i}
|
||||
<button
|
||||
type="button"
|
||||
class="block w-full text-left px-2 py-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded
|
||||
class="block w-full text-left px-2 {isMobile
|
||||
? 'py-3'
|
||||
: 'py-1'} hover:bg-gray-100 dark:hover:bg-gray-700 rounded
|
||||
{selectedIndex === i ? 'bg-gray-100 dark:bg-gray-700' : ''}"
|
||||
onmousedown={() => onSelect(word)}
|
||||
ontouchstart={(e) => handleTouchSelect(e, word)}
|
||||
role="option"
|
||||
aria-selected={selectedIndex === i}
|
||||
style:touch-action="manipulation"
|
||||
>
|
||||
{word}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Mobile-specific styles */
|
||||
@media (max-width: 768px) {
|
||||
button {
|
||||
padding: 12px 8px;
|
||||
margin-bottom: 4px;
|
||||
font-size: 16px; /* Minimum readable size on mobile */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user