aboutsummaryrefslogtreecommitdiffstats
path: root/code/frontend/src/utils/ui.ts
diff options
context:
space:
mode:
authorivar <i@oiee.no>2024-04-28 22:37:30 +0200
committerivar <i@oiee.no>2024-04-28 22:37:30 +0200
commitced66c5807575cd29f6aa5632e8ad02b38c8448a (patch)
tree01760648ee293a2aef2288328014b5747d2192b4 /code/frontend/src/utils/ui.ts
parent691ad60d7bff5934053d87267c4e303ef3ed5f97 (diff)
downloadgreatoffice-ced66c5807575cd29f6aa5632e8ad02b38c8448a.tar.xz
greatoffice-ced66c5807575cd29f6aa5632e8ad02b38c8448a.zip
WIP new frontend
Diffstat (limited to 'code/frontend/src/utils/ui.ts')
-rw-r--r--code/frontend/src/utils/ui.ts56
1 files changed, 56 insertions, 0 deletions
diff --git a/code/frontend/src/utils/ui.ts b/code/frontend/src/utils/ui.ts
new file mode 100644
index 0000000..019b8f6
--- /dev/null
+++ b/code/frontend/src/utils/ui.ts
@@ -0,0 +1,56 @@
+import { type ClassValue, clsx } from 'clsx'
+import { cubicOut } from 'svelte/easing'
+import { twMerge } from 'tailwind-merge'
+import type { TransitionConfig } from 'svelte/transition'
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+}
+
+type FlyAndScaleParams = {
+ y?: number
+ x?: number
+ start?: number
+ duration?: number
+}
+
+export function flyAndScale(
+ node: Element,
+ params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
+): TransitionConfig {
+ const style = getComputedStyle(node)
+ const transform = style.transform === 'none' ? '' : style.transform
+
+ const scaleConversion = (valueA: number, scaleA: [number, number], scaleB: [number, number]) => {
+ const [minA, maxA] = scaleA
+ const [minB, maxB] = scaleB
+
+ const percentage = (valueA - minA) / (maxA - minA)
+ const valueB = percentage * (maxB - minB) + minB
+
+ return valueB
+ }
+
+ const styleToString = (style: Record<string, number | string | undefined>): string => {
+ return Object.keys(style).reduce((str, key) => {
+ if (style[key] === undefined) return str
+ return str + `${key}:${style[key]};`
+ }, '')
+ }
+
+ return {
+ duration: params.duration ?? 200,
+ delay: 0,
+ css: (t) => {
+ const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0])
+ const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0])
+ const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1])
+
+ return styleToString({
+ transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
+ opacity: t
+ })
+ },
+ easing: cubicOut
+ }
+}