SveltUse - Utility functions library

website·Indexed 29 days ago

https://sveltuse.pages.dev

A collection of essential Svelte and SvelteKit Composition Utilities. The library provides a wide range of reactive utilities, including state management (useStates, useCounter), browser API wrappers (useClipboard, usePermission, useEyeDropper), and DOM interaction tools (useScroll, useInfiniteScroll, useResizeObserver), with many implementations ported from VueUse.

Tokens
9.9K
Snippets
59
Records
65
Agent score
74%

What's inside SveltUse

  1. Manage system clipboard with useClipboard

    The useClipboard hook provides a reactive interface to the Web Clipboard API. It allows you to asynchronously read from and write to the system clipboard. Access is subject to the Permissions API; without user permission, reading or altering clipboard contents is not permitted.

    Returned values:

    • text: A reactive store containing the current clipboard content.
    • isSupported: A reactive store indicating if the browser supports the Clipboard API.
    • copy: A function used to write a string to the clipboard.

    To support browsers that do not implement the Clipboard API, set the legacy: true option to enable document.execCommand as a fallback.

    import { useClipboard } from 'sveltuse';
    
    const { text, isSupported, copy } = useClipboard();
    
    // To copy text:
    copy('Hello World');
    
    // To use legacy fallback:
    const { copy } = useClipboard({ legacy: true });
  2. Track mouse position with useMouse

    The useMouse hook provides reactive coordinates (x, y) and the sourceType of the mouse event. By default, touch events are enabled. To restrict tracking to mouse events only, set the touch option to false. The hook utilizes the dragover event to maintain position tracking during drag operations.
    import { useMouse } from 'sveltuse'
    
    // Basic usage: tracks global mouse position
    const { x, y, sourceType } = useMouse()
    
    // Disable touch event tracking
    const { x: mouseX, y: mouseY } = useMouse({ touch: false })
  3. Debounce a function using useDebounceFn

    Use useDebounceFn to create a debounced version of a function. The function will only execute after the specified delay (in milliseconds) has elapsed since the last call. This is useful for performance-heavy operations like window resize listeners or search input handlers.
    import { useDebounceFn } from 'sveltuse'
    
    const debouncedFn = useDebounceFn(() => {
      // do something
    }, 1000)
    
    window.addEventListener('resize', debouncedFn)
  4. Manually trigger Object URL creation for non-store variables

    If the source is a getter function returning a plain variable (instead of a Svelte store), the hook cannot automatically watch for changes. In this case, you must call the .create() method on the returned store to manually trigger the generation of the Object URL.
    import { useObjectUrl } from 'sveltuse'
    
    let file: File
    const fileUrl = useObjectUrl(() => file)
    
    const onInputFile = (event: any) => {
        file = event.target.files[0]
        fileUrl.create() // Manually trigger URL creation
    }
  5. Run Playwright tests before submitting a PR

    Before submitting a Pull Request to SveltUse, ensure all tests pass by running the test suite. You can run the full suite or target a specific test file using the Playwright CLI.
    # Run all tests
    npm run test
    
    # Run a specific test file
    npx playwright test tests/typography.spec.ts
  6. Handle dynamic event targets using Svelte stores with useEventListener

    When the target element of an event listener changes dynamically (e.g., due to conditional rendering), you can pass a Svelte store as the first argument to useEventListener. The hook will automatically remove the listener from the old target and attach it to the new target whenever the store value updates.
    import { writable } from 'svelte/store'
    import { useEventListener } from 'sveltuse'
    
    let container: HTMLDivElement | null = null
    let containerStore = writable<HTMLDivElement | null>(container)
    let message = ''
    
    // Listener automatically updates when containerStore changes
    useEventListener(containerStore, 'click', (event) => {
      if (event.target) {
        message = 'Clicked on ' + event.target.innerText
      }
    })
    
    // Update the store when the bound element changes
    $: {
      containerStore.set(container)
    }
  7. Pick colors using useEyeDropper

    The useEyeDropper hook provides a reactive interface for the native Web EyeDropper API. It allows you to trigger the browser's color picker and reactively track the selected color in sRGB hex format. It also provides a boolean to check if the EyeDropper API is supported by the current browser.
    <script lang="ts">
    	import { useEyeDropper } from 'sveltuse'
    
    	// isSupported: Read-only store indicating if the browser supports EyeDropper
    	// sRGBHex: Store containing the hex code of the picked color
    	// open: Function to trigger the EyeDropper tool
    	const { isSupported, sRGBHex, open } = useEyeDropper()
    </script>
    
    <div>
    	<p>Supported: {$isSupported}</p>
    	<p>Selected Color: {$sRGBHex}</p>
    	<button on:click={() => open()}>Open Eye Dropper</button>
    </div>
  8. Render PDFs in Svelte using usePDF

    The usePDF integration allows you to render PDF files using pdfjs-dist. It provides a set of stores and actions to manage the PDF viewport, page navigation, zooming, and rendering of both full pages and thumbnails.
    import usePDF from 'sveltuse/integrations/usePDF'
    
    let pagesContainer: HTMLDivElement
    
    const { 
      scale, 
      viewport, 
      pageNumber, 
      pageNumbers, 
      pageRenderer, 
      thumbnailRenderer, 
      goToNextPage, 
      goToPreviousPage, 
      zoomIn, 
      zoomOut, 
      download, 
      print 
    } = usePDF({
      initialScale: 0.9,
      src: '/pdf/sample.pdf',
      pagesContainerGetter: () => pagesContainer
    })
  9. Implement infinite scrolling with useInfiniteScroll

    The useInfiniteScroll function enables infinite scrolling for a specific element. It triggers a callback function when the user scrolls near the bottom of the element. It returns a store (e.g., isLoading) to track the loading state of the asynchronous operation.
    import { useInfiniteScroll } from 'sveltuse'
    import sleep from 'sveltuse/utils/sleep'
    
    let el: HTMLElement
    let data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    const { isLoading } = useInfiniteScroll(
    	() => el,
    	async () => {
    		await sleep(500)
    		const length = data.length + 1
    		data = [...data, ...Array.from({ length: 10 }, (_, i) => length + i)]
    	},
    	{
    		distance: 10, // distance from bottom to trigger
    		interval: 100 // check interval in ms
    	}
    )

    <!-- HTML implementation --> <div bind:this={el} class="overflow-y-scroll h-[300px]"> {#each data as item} <div>{item}</div> {/each} </div>

    {#if $isLoading} <span>Loading...</span> {/if}

  10. Manage reactive state with useStates

    The useStates hook creates a reactive state variable that allows you to toggle between a predefined set of states (such as a list of strings, an enum, or an object). To access the current value of the state reactively in Svelte, use the $ prefix (e.g., $currentColor).
    import { useStates } from 'sveltuse'
    
    // Using a constant array for better autocomplete
    const colors = ['red', 'green', 'blue'] as const
    const currentColor = useStates(colors, 'red')
    
    // Update the state
    currentColor.set('green')
    
    // Using an enum
    enum Status {
    	Active,
    	Pending,
    	InProgress,
    	Cancelled
    }
    const currentStatus = useStates(Status, Status.Active)
    
    // Update using value or callback
    currentStatus.set(Status.InProgress)
    currentStatus.set((v) => v.Cancelled)
  11. Use the dScroll directive for scroll events

    The dScroll directive can be applied directly to an element to handle scroll events. It accepts a callback function that receives the UseScrollReturn object containing the reactive scroll state.
    <script lang="ts">
      import { dScroll, type UseScrollReturn } from 'sveltuse'
    
      const onScroll = (e: UseScrollReturn) => {
        console.log('Scroll state updated:', e)
      }
    </script>
    
    <div use:dScroll={onScroll} class="overflow-auto h-32 w-full">
      <div class="h-[2400px] w-[2400px]" />
    </div>
  12. Observe element dimension changes with useResizeObserver

    The useResizeObserver hook reports changes to the dimensions of an Element's content or the border-box. It takes a getter function for the target element and a callback function that executes whenever the element is resized. The callback receives an array of ResizeObserverEntry objects containing the contentRect (width and height) of the observed element.
    import { useResizeObserver } from 'sveltuse'
    
    let text = ''
    let el: HTMLTextAreaElement
    
    useResizeObserver(
    	() => el,
    	(entries) => {
    		const [entry] = entries
    		const { width, height } = entry.contentRect
    		text = `width: ${width}\nheight: ${height}`
    	}
    )