From 592b60445815ea6a7170a44da0ded838e75cd393 Mon Sep 17 00:00:00 2001 From: PurelyAnecdotal <58897346+PurelyAnecdotal@users.noreply.github.com> Date: Mon, 30 Dec 2024 15:04:21 -1000 Subject: [PATCH] Add number-flow component for grade percentage display (#113) --- bun.lock | 5 +++ package.json | 1 + src/routes/(authed)/grades/+page.svelte | 8 +++-- .../(authed)/grades/[index]/+page.svelte | 35 ++++++++++++++----- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/bun.lock b/bun.lock index af3bf9e..ce28430 100755 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ }, "devDependencies": { "@eslint/compat": "^1.2.4", + "@number-flow/svelte": "^0.2.3", "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.15.0", "@sveltejs/vite-plugin-svelte": "^5.0.3", @@ -148,6 +149,8 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@number-flow/svelte": ["@number-flow/svelte@0.2.3", "", { "dependencies": { "esm-env": "^1.1.4", "number-flow": "0.4.2" }, "peerDependencies": { "svelte": "^4 || ^5" } }, "sha512-19jagH1P9Oagh5vckNDENVekqP1cnjarhi9Yaf2YdktbIzc1FeyiHeyRbyLdsuJiYLlk0KHdFP/WKE+MSod1Mg=="], + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], "@polka/url": ["@polka/url@1.0.0-next.28", "", {}, "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw=="], @@ -614,6 +617,8 @@ "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], + "number-flow": ["number-flow@0.4.2", "", { "dependencies": { "esm-env": "^1.1.4" } }, "sha512-YLN73/m8BUU4r/6mq9zqLdpFKt3LSPPRectOECheA9jtNWF4PP8EIz0+Z1giqu/x9nS86KnKwwouLXXiqnjhQQ=="], + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], diff --git a/package.json b/package.json index 3efe43e..07f6c9b 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@eslint/compat": "^1.2.4", + "@number-flow/svelte": "^0.2.3", "@sveltejs/adapter-vercel": "^5.5.2", "@sveltejs/kit": "^2.15.0", "@sveltejs/vite-plugin-svelte": "^5.0.3", diff --git a/src/routes/(authed)/grades/+page.svelte b/src/routes/(authed)/grades/+page.svelte index 8502183..de638f2 100644 --- a/src/routes/(authed)/grades/+page.svelte +++ b/src/routes/(authed)/grades/+page.svelte @@ -1,5 +1,6 @@ <script lang="ts"> import { getColorForGrade, removeClassID } from '$lib'; + import NumberFlow from '@number-flow/svelte'; import { Alert, Button, Card, Dropdown, DropdownItem, Progressbar } from 'flowbite-svelte'; import ChevronDownOutline from 'flowbite-svelte-icons/ChevronDownOutline.svelte'; import ChevronUpOutline from 'flowbite-svelte-icons/ChevronUpOutline.svelte'; @@ -89,8 +90,11 @@ > <span class="mr-2 line-clamp-1">{removeClassID(title)}</span> <span class="ml-auto mr-2 shrink-0"> - {grade} - {parseFloat(percent)}% + <NumberFlow + prefix={grade + ' '} + value={parseFloat(percent) / 100} + format={{ style: 'percent', maximumFractionDigits: 3 }} + /> </span> <Progressbar diff --git a/src/routes/(authed)/grades/[index]/+page.svelte b/src/routes/(authed)/grades/[index]/+page.svelte index fa72d9e..062bf3c 100644 --- a/src/routes/(authed)/grades/[index]/+page.svelte +++ b/src/routes/(authed)/grades/[index]/+page.svelte @@ -21,6 +21,7 @@ type ReactiveAssignment, type RealAssignment } from '$lib/assignments'; + import NumberFlow from '@number-flow/svelte'; import { Alert, Button, @@ -164,6 +165,22 @@ } let calcWarningOpen = $state(false); + + const prefix = $derived( + hypotheticalMode ? '' : synergyCourse?.Marks.Mark._CalculatedScoreString + ' ' + ); + + const value = $derived( + hypotheticalMode + ? hypotheticalGrade / 100 + : synergyCourse + ? parseFloat(synergyCourse.Marks.Mark._CalculatedScoreRaw) / 100 + : undefined + ); + + // https://github.com/barvian/number-flow/blob/e9fc6999417df7cb7e7b290f7f2019f570c18cc7/packages/number-flow/src/index.ts#L73 + const easing = + 'linear(0,.005,.019,.039,.066,.096,.129,.165,.202,.24,.278,.316,.354,.39,.426,.461,.494,.526,.557,.586,.614,.64,.665,.689,.711,.731,.751,.769,.786,.802,.817,.831,.844,.856,.867,.877,.887,.896,.904,.912,.919,.925,.931,.937,.942,.947,.951,.955,.959,.962,.965,.968,.971,.973,.976,.978,.98,.981,.983,.984,.986,.987,.988,.989,.99,.991,.992,.992,.993,.994,.994,.995,.995,.996,.996,.9963,.9967,.9969,.9972,.9975,.9977,.9979,.9981,.9982,.9984,.9985,.9987,.9988,.9989,1)'; </script> <svelte:head> @@ -176,14 +193,16 @@ {courseName} </span> <span class="flex shrink-0 items-center text-2xl"> - {#if hypotheticalMode} - {#if !categories && !rawGradeCalcMatches} - <ExclamationCircleSolid class="mr-2 focus:outline-none" /> - {/if} - {Math.round(hypotheticalGrade * 1000) / 1000}% - {:else} - {synergyCourse.Marks.Mark._CalculatedScoreString} - {synergyCourse.Marks.Mark._CalculatedScoreRaw}% + {#if hypotheticalMode && !categories && !rawGradeCalcMatches} + <ExclamationCircleSolid class="mr-2 focus:outline-none" /> + {/if} + {#if value} + <NumberFlow + {prefix} + {value} + format={{ style: 'percent', maximumFractionDigits: 3 }} + spinTiming={{ duration: 400, easing }} + /> {/if} </span> </div>