-
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
tglide
committed
Mar 11, 2024
1 parent
6a1389d
commit 30cb9b4
Showing
9 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./withDebounce.svelte.js"; | ||
export * from "./withElementSize.svelte.js"; |
43 changes: 43 additions & 0 deletions
43
packages/withrunes/src/lib/functions/withElementSize.svelte.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import type { ValueOrGetter } from "$lib/internal/types.js"; | ||
import { boxed } from "$lib/internal/utils/boxed.svelte.js"; | ||
|
||
type Options = { | ||
initialSize?: { | ||
width: number; | ||
height: number; | ||
}; | ||
box?: "content-box" | "border-box"; | ||
}; | ||
|
||
export function withElementSize( | ||
_node: ValueOrGetter<HTMLElement | undefined>, | ||
options: Options = { | ||
box: "border-box", | ||
} | ||
) { | ||
const node = boxed(_node); | ||
const size = $state({ | ||
width: options.initialSize?.width ?? 0, | ||
height: options.initialSize?.height ?? 0, | ||
}); | ||
|
||
$effect(() => { | ||
if (!node.value) return; | ||
|
||
const observer = new ResizeObserver((entries) => { | ||
for (const entry of entries) { | ||
const boxSize = options.box === "content-box" ? entry.contentBoxSize : entry.borderBoxSize; | ||
const boxSizeArr = Array.isArray(boxSize) ? boxSize : [boxSize]; | ||
size.width = boxSizeArr.reduce((acc, size) => Math.max(acc, size.inlineSize), 0); | ||
size.height = boxSizeArr.reduce((acc, size) => Math.max(acc, size.blockSize), 0); | ||
} | ||
}); | ||
observer.observe(node.value); | ||
|
||
return () => { | ||
observer.disconnect(); | ||
}; | ||
}); | ||
|
||
return size; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export type FunctionArgs<Args extends any[] = any[], Return = void> = (...args: Args) => Return; | ||
|
||
export type Getter<T> = () => T; | ||
export type ValueOrGetter<T> = T | (() => T); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type { ValueOrGetter } from "../types.js"; | ||
import { isFunction } from "./is.js"; | ||
|
||
export function boxed<T>(value: ValueOrGetter<T>) { | ||
return { | ||
get value() { | ||
return isFunction(value) ? value() : value; | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export function isFunction(value: unknown): value is (...args: unknown[]) => unknown { | ||
return typeof value === "function"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--- | ||
title: WithElementSize | ||
description: A higher-order function that debounces the execution of a function. | ||
--- | ||
|
||
<script> | ||
import { WithElementSizeDemo } from '$lib/components/demos'; | ||
</script> | ||
|
||
## Demo | ||
|
||
<WithElementSizeDemo /> | ||
|
||
## Usage | ||
|
||
```svelte | ||
<script lang="ts"> | ||
import { withElementSize } from "withrunes"; | ||
let count = $state(0); | ||
let logged = $state(""); | ||
let isFirstTime = $state(true); | ||
const logCount = withElementSize(() => { | ||
if (isFirstTime) { | ||
isFirstTime = false; | ||
logged = `You pressed the button ${count} times!`; | ||
} else { | ||
logged = `You pressed the button ${count} times since last time!`; | ||
} | ||
count = 0; | ||
}, 1000); | ||
function ding() { | ||
count++; | ||
logCount(); | ||
} | ||
</script> | ||
<div> | ||
<button onclick={ding}>DING DING DING</button> | ||
<p>{logged || "Press the button!"}</p> | ||
</div> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export { default as WithDebounceDemo } from "./with-debounce.svelte"; | ||
export { default as WithElementSizeDemo } from "./with-element-size.svelte"; |
15 changes: 15 additions & 0 deletions
15
sites/docs/src/lib/components/demos/with-element-size.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<script lang="ts"> | ||
import { withElementSize } from "withrunes"; | ||
let el: HTMLElement | undefined = $state(undefined); | ||
const size = withElementSize(() => el); | ||
const text = $derived(`Width: ${size.width}\nHeight: ${size.height}`); | ||
</script> | ||
|
||
<div class="bg-card rounded-md p-8"> | ||
<textarea | ||
bind:this={el} | ||
class="h-[200px] min-h-[100px] w-[300px] min-w-[200px] resize rounded-md bg-neutral-800 p-4" | ||
value={text} | ||
/> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters