Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to Svelte 5 #11

Merged
merged 8 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "paper-cost",
"version": "1.4.0",
"version": "1.7.0",
"private": true,
"scripts": {
"dev": "vite dev",
Expand All @@ -12,24 +12,22 @@
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test:ui": "playwright test",
"test:unit": "vitest",
"lint": "prettier --plugin-search-dir . --check .",
"format": "prettier --plugin-search-dir . --write ."
"lint": "prettier --check .",
"format": "prettier --write ."
},
"devDependencies": {
"@iconify/svelte": "^4.0.2",
"@playwright/test": "^1.46.1",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-vercel": "^5.4.1",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@sveltejs/kit": "^2.7.2",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@types/mixpanel-browser": "^2.49.0",
"@types/node": "^22.5.0",
"autoprefixer": "^10.4.14",
"dotenv": "^16.4.5",
"postcss": "^8.4.27",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1",
"svelte": "^4.0.5",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.7",
"svelte-check": "^3.4.3",
"tailwindcss": "^3.3.3",
"tslib": "^2.4.1",
Expand All @@ -44,8 +42,8 @@
"@supabase/supabase-js": "^2.44.3",
"dayjs": "^1.11.11",
"mixpanel-browser": "^2.55.1",
"svelte": "^5.1.0",
"svelte-persisted-store": "^0.11.0",
"svelte-sonner": "^0.3.27",
"tippy.js": "^6.3.7"
"svelte-sonner": "^0.3.27"
}
}
3 changes: 2 additions & 1 deletion src/lib/elements/About.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script lang="ts">
import { version } from '$app/environment'
import type { User } from '@supabase/supabase-js'
export let user: User | null = null

const { user }: { user: User | null } = $props()
</script>

<div class="flex flex-col text-center items-center">
Expand Down
18 changes: 10 additions & 8 deletions src/lib/elements/Button.svelte
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
<script lang="ts">
import { onMount } from 'svelte'
type ButtonProp = {
text: string
onclick: () => void
classNames: string
type: 'button' | 'submit' | 'reset'
}

export let disabled = false
export let text = ''
export let classNames = ''
export let type: 'button' | 'submit' | 'reset' = 'button'
let { text, classNames, type = 'button', onclick, ...rest }: ButtonProp = $props()

let buttonRef: HTMLButtonElement

onMount(() => {
$effect(() => {
if (buttonRef) {
buttonRef.type = type
}
})
</script>

<button
{onclick}
{...rest}
bind:this={buttonRef}
{disabled}
{type}
class="border border-gray-400 rounded-md text-teal-600 font-semibold px-3 py-1 w-fit disabled:text-opacity-60 {classNames}"
on:click
>
{text}
</button>
14 changes: 9 additions & 5 deletions src/lib/elements/Footer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
import { enhance } from '$app/forms'
import mixpanel from '$lib/utils/mixpanel'

export let showSettings = false
export let showAbout = false
export let loading = false
type FooterProp = { showSettings: boolean; showAbout: boolean; loading: boolean }

let {
showSettings = $bindable(),
showAbout = $bindable(),
loading = $bindable()
}: FooterProp = $props()

const navItems = [
{ href: '/', label: 'Home', icon: 'clarity:home-line' },
Expand All @@ -34,7 +38,7 @@
{label}
</a>
{/each}
<button on:click={toggleSettings} class="flex flex-row gap-1 items-center">
<button onclick={toggleSettings} class="flex flex-row gap-1 items-center">
<Icon icon="solar:settings-linear" /> Settings
</button>
</nav>
Expand All @@ -45,7 +49,7 @@
class="absolute w-20 right-3 bottom-11 flex flex-col items-start divide-y divide-orange-400 gap-1 bg-slate-50 p-2 rounded"
>
<button
on:click={() => {
onclick={() => {
showAbout = true
toggleSettings()
}}>About</button
Expand Down
55 changes: 39 additions & 16 deletions src/lib/elements/HistoryRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@
import { get40Percent, type CostHistoryType } from '$lib/utils/services'
import Icon from '@iconify/svelte'
import dayjs from 'dayjs'
import { createEventDispatcher } from 'svelte'

export let cost: CostHistoryType
export let isTrash: boolean = false
let {
cost,
isTrash = false,
ondelete,
onrestore
}: {
cost: CostHistoryType
isTrash?: boolean
ondelete: (id: string) => void
onrestore?: (id: string) => void
} = $props()

const dispatch = createEventDispatcher()

let deleteConfirm = ''
let deleteConfirm = $state('')
</script>

<div class="flex flex-col gap-1 items-center w-full p-1 border border-dashed rounded shadow-sm">
Expand All @@ -29,18 +35,27 @@
</p>

<div class="flex flex-row items-center gap-[2px]">
<button
class:hidden={deleteConfirm == cost.id || !isTrash}
class="border border-green-300 rounded text-green-600 p-[3px] w-fit disabled:border-gray-200 disabled:cursor-not-allowed disabled:text-opacity-45"
on:click|stopPropagation|preventDefault={() => dispatch('restore', cost.id)}
>
<Icon icon="ic:round-settings-backup-restore" />
</button>
{#if onrestore}
<button
class:hidden={deleteConfirm == cost.id || !isTrash}
class="border border-green-300 rounded text-green-600 p-[3px] w-fit disabled:border-gray-200 disabled:cursor-not-allowed disabled:text-opacity-45"
onclick={(e) => {
e.preventDefault()
onrestore(cost.id)
}}
>
<Icon icon="ic:round-settings-backup-restore" />
</button>
{/if}
<button
data-testid="delete-cost-history"
class:hidden={deleteConfirm == cost.id}
class="border border-red-300 rounded text-red-600 p-[3px] w-fit disabled:border-gray-200 disabled:cursor-not-allowed disabled:text-opacity-45"
on:click|stopPropagation|preventDefault={() => (deleteConfirm = cost.id || '')}
onclick={(e) => {
e.preventDefault()
e.stopPropagation()
deleteConfirm = cost.id || ''
}}
>
{#if isTrash}
<Icon icon="ic:baseline-delete-forever" />
Expand All @@ -51,14 +66,22 @@
{#if deleteConfirm == cost.id}
<button
class="border border-yellow-300 p-[3px] rounded text-yellow-600 w-fit disabled:border-gray-200 disabled:cursor-not-allowed disabled:text-opacity-45"
on:click|stopPropagation|preventDefault={() => (deleteConfirm = '')}
onclick={(e) => {
e.preventDefault()
e.stopPropagation()
deleteConfirm = ''
}}
>
<Icon icon="majesticons:multiply" width="16px" />
</button>
<button
data-testid="confirm-delete"
class="border border-green-300 p-[3px] rounded text-green-700 w-fit disabled:border-gray-200 disabled:cursor-not-allowed disabled:text-opacity-45"
on:click|stopPropagation|preventDefault={() => dispatch('delete', cost.id)}
onclick={(e) => {
e.preventDefault()
e.stopPropagation()
ondelete(cost.id)
}}
>
<Icon icon="teenyicons:tick-solid" width="15px" />
</button>
Expand Down
40 changes: 28 additions & 12 deletions src/lib/elements/Input.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
<script lang="ts">
import { focusedInputStore } from '$lib/stores'
import { makeid } from '$lib/utils/tools'
import { onMount } from 'svelte'

export let id: string = makeid(3)
export let value: string
export let name: string = ''
export let type: string = 'number'
export let disabled: boolean = false
export let classNames: string = ''
type InputType = {
id?: string
value: string
name: string
type?: string
disabled?: boolean
classNames?: string
onkeydown?: (event: KeyboardEvent) => void
onfocus?: () => void
}

let {
id = makeid(3),
value = $bindable(),
name,
classNames,
disabled = false,
type = 'number',
onkeydown,
onfocus,
...rest
}: InputType = $props()

let inputRef: HTMLInputElement

onMount(() => {
$effect(() => {
if (inputRef) {
inputRef.type = type
}
Expand All @@ -27,10 +42,11 @@
{disabled}
class="input-field focus:!border-[1.5px] focus:!border-teal-500 focus:outline-none {classNames}"
bind:value
on:keydown
on:focus
on:focus={() => ($focusedInputStore = inputRef)}
{...$$restProps}
{onkeydown}
onfocus={() => {
$focusedInputStore = inputRef
}}
{...rest}
/>

<style lang="postcss">
Expand Down
15 changes: 12 additions & 3 deletions src/lib/elements/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
import { makeid, receive, send } from '$lib/utils/tools'
import Icon from '@iconify/svelte'

export let show = false
interface Props {
show?: boolean
children?: import('svelte').Snippet
}

let { show = $bindable(false), children }: Props = $props()
const id = makeid(6)
</script>

Expand All @@ -14,10 +19,14 @@
>
<button
class="absolute top-0 right-0 p-[3px] rounded-full w-fit"
on:click|stopPropagation|preventDefault={() => (show = false)}
onclick={(e) => {
e.preventDefault()
e.stopPropagation()
show = false
}}
>
<Icon icon="majesticons:multiply" width="20px" />
</button>
<slot />
{@render children?.()}
</div>
</div>
51 changes: 36 additions & 15 deletions src/lib/elements/PaperItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,61 @@
import Input from './Input.svelte'
import { receive, send } from '$lib/utils/tools'
import { fields, placeholders } from '$lib/utils/constants'
import { createEventDispatcher } from 'svelte'
import type { Paper } from '$lib/utils/services'

export let paper: Paper
export let index: number
export let totalPaper: number
export let perPaperResult: Map<string, number>
let {
paper = $bindable(),
index,
totalPaper,
perPaperResult,
onkeydown,
onremove
}: {
paper: Paper
index: number
totalPaper: number
perPaperResult: Map<string, number>
onkeydown: (event: KeyboardEvent) => void
onremove: () => void
} = $props()

const dispatch = createEventDispatcher()
$effect(() => {
console.log(paper)
})
</script>

<div
id={paper.id}
id={paper?.id}
class="flex flex-row items-center justify-between rounded"
in:receive={{ key: paper.id, duration: 250 }}
out:send={{ key: paper.id, duration: 250 }}
in:receive={{ key: paper?.id, duration: 250 }}
out:send={{ key: paper?.id, duration: 250 }}
>
<div class="flex flex-row gap-[3px] items-center overflow-x-auto">
<button
disabled={totalPaper == 1 && index == 0}
class="border border-gray-400 rounded-md text-red-600 p-1 w-fit disabled:border-gray-200 disabled:cursor-not-allowed disabled:text-opacity-45"
on:click={() => dispatch('remove')}
onclick={() => onremove()}
>
<Icon icon="ph:trash-light" width="16px" />
</button>
{#each fields as field}
<Input name={field} bind:value={paper[field]} placeholder={placeholders[field]} on:keydown />
{/each}
{#if paper}
{#each fields as field}
<Input
name={field}
bind:value={paper[field]}
placeholder={placeholders[field]}
{onkeydown}
/>
{/each}
{/if}
</div>
<div class="flex flex-grow justify-center px-1">
<p
class="{perPaperResult.get(paper.id) ? 'font-semibold' : 'font-light text-gray-400'} pr-[2px]"
class="{perPaperResult.get(paper?.id)
? 'font-semibold'
: 'font-light text-gray-400'} pr-[2px]"
>
= {perPaperResult.get(paper.id)?.toFixed(2) || 'total'}
= {perPaperResult.get(paper?.id)?.toFixed(2) || 'total'}
</p>
</div>
</div>
4 changes: 2 additions & 2 deletions src/lib/elements/Result.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts">
import { get40Percent } from '$lib/utils/services'

export let total: number = 0
let { total = 0 }: { total: number } = $props()

$: _40Percent = get40Percent(total)
const _40Percent = $derived(get40Percent(total))
</script>

<div class="flex flex-col gap-1 w-full border shadow-md rounded py-1 px-2">
Expand Down
1 change: 1 addition & 0 deletions src/lib/elements/SingleLine.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div class="w-full bg-gradient-to-r from-transparent via-slate-600/10 to-transparent p-[1px]"></div>
Loading