mirror of
https://github.com/aculix/negotium.git
synced 2026-09-11 07:28:17 +00:00
chore: upgrade to svelte 5 and vite 8
Svelte 4.2 to 5.56, Vite 5 to 8, vite-plugin-svelte 3 to 7. The old tree wouldn't resolve incrementally, because a stale vite-plugin-svelte-inspector pinned the v3 peer, so this is a clean reinstall. Clears all 7 npm audit advisories, including a high-severity Rollup path traversal. Reactivity moves to runes: $state, $derived, $effect. Event directives become properties, and main.js uses mount(). Also drops inputElement, a bind:this target nothing ever read.
This commit is contained in:
Generated
+238
-1519
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -12,9 +12,9 @@
|
|||||||
"test:watch": "vitest"
|
"test:watch": "vitest"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
||||||
"svelte": "^4.2.0",
|
"svelte": "^5.56.9",
|
||||||
"vite": "^5.0.0",
|
"vite": "^8.2.1",
|
||||||
"vitest": "^4.1.10"
|
"vitest": "^4.1.10"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
+27
-28
@@ -12,16 +12,15 @@
|
|||||||
|
|
||||||
const storage = createStorage();
|
const storage = createStorage();
|
||||||
|
|
||||||
let tasks = [];
|
let tasks = $state([]);
|
||||||
let newTask = '';
|
let newTask = $state('');
|
||||||
let darkMode = false;
|
let darkMode = $state(false);
|
||||||
let inputElement;
|
let isLoading = $state(true);
|
||||||
let isLoading = true;
|
|
||||||
let isInitialized = false;
|
let isInitialized = false;
|
||||||
let todayKey = toKey(new Date());
|
let todayKey = $state(toKey(new Date()));
|
||||||
let selectedKey = todayKey;
|
let selectedKey = $state(toKey(new Date()));
|
||||||
let draggedItem = null;
|
let draggedItem = $state(null);
|
||||||
let draggedOverIndex = null;
|
let draggedOverIndex = $state(null);
|
||||||
let midnightTimer = null;
|
let midnightTimer = null;
|
||||||
|
|
||||||
/** Single write path, so persistence cannot drift out of step with the list.
|
/** Single write path, so persistence cannot drift out of step with the list.
|
||||||
@@ -139,15 +138,16 @@
|
|||||||
if (document.visibilityState === 'visible') runRollover();
|
if (document.visibilityState === 'visible') runRollover();
|
||||||
}
|
}
|
||||||
|
|
||||||
$: currentDateDisplay = formatLong(selectedKey);
|
const currentDateDisplay = $derived(formatLong(selectedKey));
|
||||||
$: buttonText = labelFor(selectedKey, todayKey);
|
const buttonText = $derived(labelFor(selectedKey, todayKey));
|
||||||
|
|
||||||
$: remainingTasks = tasks.filter(task => !task.completed).length;
|
const remainingTasks = $derived(tasks.filter(task => !task.completed).length);
|
||||||
$: completedTasks = tasks.filter(task => task.completed).length;
|
const completedTasks = $derived(tasks.filter(task => task.completed).length);
|
||||||
|
|
||||||
$: if (darkMode !== undefined && isInitialized) {
|
$effect(() => {
|
||||||
|
if (!isInitialized) return;
|
||||||
storage.saveTheme(darkMode ? 'dark' : 'light');
|
storage.saveTheme(darkMode ? 'dark' : 'light');
|
||||||
}
|
});
|
||||||
|
|
||||||
function initLottie(node) {
|
function initLottie(node) {
|
||||||
let instance = null;
|
let instance = null;
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:keydown={handleKeydown} />
|
<svelte:window onkeydown={handleKeydown} />
|
||||||
|
|
||||||
<div class="app" class:dark={darkMode}>
|
<div class="app" class:dark={darkMode}>
|
||||||
{#if isLoading}
|
{#if isLoading}
|
||||||
@@ -238,7 +238,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<button class="today-btn" aria-label="Switch between Today and Tomorrow" on:click={switchDate}>
|
<button class="today-btn" aria-label="Switch between Today and Tomorrow" onclick={switchDate}>
|
||||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" stroke="currentColor" stroke-width="2"/>
|
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" stroke="currentColor" stroke-width="2"/>
|
||||||
<line x1="16" y1="2" x2="16" y2="6" stroke="currentColor" stroke-width="2"/>
|
<line x1="16" y1="2" x2="16" y2="6" stroke="currentColor" stroke-width="2"/>
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
class="theme-toggle"
|
class="theme-toggle"
|
||||||
on:click={toggleTheme}
|
onclick={toggleTheme}
|
||||||
aria-label={darkMode ? 'Switch to light mode' : 'Switch to dark mode'}
|
aria-label={darkMode ? 'Switch to light mode' : 'Switch to dark mode'}
|
||||||
>
|
>
|
||||||
<svg class="theme-icon" class:rotated={darkMode} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="theme-icon" class:rotated={darkMode} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
@@ -282,12 +282,11 @@
|
|||||||
|
|
||||||
<div class="task-input-container">
|
<div class="task-input-container">
|
||||||
<input
|
<input
|
||||||
bind:this={inputElement}
|
|
||||||
bind:value={newTask}
|
bind:value={newTask}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="+ Add a task"
|
placeholder="+ Add a task"
|
||||||
class="task-input"
|
class="task-input"
|
||||||
on:keydown={handleKeydown}
|
onkeydown={handleKeydown}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -296,7 +295,7 @@
|
|||||||
{remainingTasks} {remainingTasks === 1 ? 'task' : 'tasks'} remaining
|
{remainingTasks} {remainingTasks === 1 ? 'task' : 'tasks'} remaining
|
||||||
</span>
|
</span>
|
||||||
{#if completedTasks > 0}
|
{#if completedTasks > 0}
|
||||||
<button class="clear-completed" on:click={clearCompleted}>
|
<button class="clear-completed" onclick={clearCompleted}>
|
||||||
Clear completed
|
Clear completed
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -319,11 +318,11 @@
|
|||||||
draggable="true"
|
draggable="true"
|
||||||
in:fly={{ y: -10, duration: 300, delay: index * 30, easing: cubicOut }}
|
in:fly={{ y: -10, duration: 300, delay: index * 30, easing: cubicOut }}
|
||||||
out:fly={{ x: 30, opacity: 0, duration: 250, delay: index * 20, easing: cubicOut }}
|
out:fly={{ x: 30, opacity: 0, duration: 250, delay: index * 20, easing: cubicOut }}
|
||||||
on:dragstart={(e) => handleDragStart(e, index)}
|
ondragstart={(e) => handleDragStart(e, index)}
|
||||||
on:dragover={(e) => handleDragOver(e, index)}
|
ondragover={(e) => handleDragOver(e, index)}
|
||||||
on:dragend={handleDragEnd}
|
ondragend={handleDragEnd}
|
||||||
on:dragleave={handleDragLeave}
|
ondragleave={handleDragLeave}
|
||||||
on:keydown={(e) => handleTaskKeydown(e, task.id)}
|
onkeydown={(e) => handleTaskKeydown(e, task.id)}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
role="button"
|
role="button"
|
||||||
aria-label={task.completed ? `Completed: ${task.text}` : `Incomplete: ${task.text}`}
|
aria-label={task.completed ? `Completed: ${task.text}` : `Incomplete: ${task.text}`}
|
||||||
@@ -331,7 +330,7 @@
|
|||||||
<button
|
<button
|
||||||
class="checkbox"
|
class="checkbox"
|
||||||
class:checked={task.completed}
|
class:checked={task.completed}
|
||||||
on:click={() => toggleTask(task.id)}
|
onclick={() => toggleTask(task.id)}
|
||||||
aria-label={task.completed ? 'Mark as incomplete' : 'Mark as complete'}
|
aria-label={task.completed ? 'Mark as incomplete' : 'Mark as complete'}
|
||||||
>
|
>
|
||||||
{#if task.completed}
|
{#if task.completed}
|
||||||
@@ -345,7 +344,7 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
class="delete-btn"
|
class="delete-btn"
|
||||||
on:click={() => deleteTask(task.id)}
|
onclick={() => deleteTask(task.id)}
|
||||||
aria-label="Delete task"
|
aria-label="Delete task"
|
||||||
>
|
>
|
||||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
+2
-3
@@ -1,7 +1,6 @@
|
|||||||
|
import { mount } from 'svelte';
|
||||||
import App from './App.svelte';
|
import App from './App.svelte';
|
||||||
|
|
||||||
const app = new App({
|
export default mount(App, {
|
||||||
target: document.getElementById('app'),
|
target: document.getElementById('app'),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default app;
|
|
||||||
|
|||||||
Reference in New Issue
Block a user