Skip to content

swyxio/svelte-actions

Repository files navigation

svelte-actions

A Prototype svelte actions for inclusion into official actions in future. See RFC and Discuss High Level Policy.

⚠️ Tests are kindly provided by @geoffrich - but do not rely on this library yet! APIs may change - this is a strawman for discussion.

Install Instructions

npm i svelte-actions

Available actions:

name description
clickOutside Demo - Call callback when user clicks outside a given element.
longpress Demo - Creates longpress event when mousedown above duration milliseconds.
pannable Demo - Creates panstart, panmove, panend events so you can drag elements.
lazyload Demo - Lazily attach properties to any DOM element (e.g. <img>) when it is in the window.
preventTabClose Demo - Prevent current tab from being closed by user.
shortcut Demo - Add a keyboard shortcut to a div or a button.

Included Actions

clickOutside

export function clickOutside(node: HTMLElement, params: {
	enabled: boolean, 
	callback?: (node?: HTMLElement) => void;
}): ReturnType<Action>

Call callback when user clicks outside a given element.

Demo: https://svelte.dev/repl/dae848c2157e48ab932106779960f5d5?version=3.19.2

<script>
  import {clickOutside} from 'svelte-actions'
  let open = true;
</script>


<div use:clickOutside={{ enabled: open, callback: () => open = false }}>
   <button on:click={() => open = true}>Open</button>
   {#if open}
    <span>
      Opened
    </span>
  {/if}
</div>

Discuss this action: #4

longpress

export function longpress(node: HTMLElement, duration: number): ReturnType<Action>

Creates longpress event when mousedown above duration milliseconds.

Demo: https://svelte.dev/tutorial/adding-parameters-to-actions

<script>
  import {longpress} from 'svelte-actions'
</script>

<button use:longpress={duration}
    on:longpress="{() => pressed = true}"
    on:mouseenter="{() => pressed = false}"
  >press and hold</button>

Discuss this action: #3

pannable

export function pannable(node: HTMLElement): ReturnType<Action>

Creates panstart, panmove, panend events so you can drag elements.

Demo: https://svelte.dev/tutorial/actions

<div class="box"
	use:pannable
	on:panstart={handlePanStart}
	on:panmove={handlePanMove}
	on:panend={handlePanEnd}
></div>

The events contain clientX and clientY coordinates (or diffs in the case of panmove):

  • panstart event: { detail: { x, y }}
  • panmove event: { detail: { dx, dy }}
  • panend event: { detail: { x, y }}

Discuss this action: #6

lazyload

export function lazyLoad(node: HTMLElement, attributes: Object): ReturnType<Action>

Lazily attach properties to any DOM element when it is in the window. Useful for lazy loading images, and other properties.

Demo: https://svelte.dev/repl/f12988de576b4bf9b541a2a59eb838f6?version=3.23.2

<script>
  import {lazyload} from 'svelte-actions'
</script>

<img use:lazyLoad={{src:"/myimage"}} alt="">

Discuss this action: #2

preventTabClose

export function preventTabClose(_, enabled: boolean)

Prevent current tab from being closed by user.

Demo: https://svelte.dev/repl/a95db12c1b46433baac2817a0963dc93

<script>
  import {preventTabClose} from 'svelte-actions'
  let isOn = false
</script>

<button use:preventTabClose={isOn} on:click={() => isOn = !isOn}>Click me</button>

Discuss this action: #11

shortcut

export function shortcut(node: Action, {
  control?: boolean;
  shift?: boolean;
  alt?: boolean;
  code: string;
  callback?: (node?: HTMLElement) => void;
})

Add a keyboard shortcut to a div or a button.

It either calls a callback or clicks on the node it was put on.

Demo: https://svelte.dev/repl/aca51811429c4127b1e7ff7eb67a172f?version=3.38.2

<script>
  import {shortcut} from 'svelte-actions'
	let buttonCount = 0, divCount = 0;
</script>

<button use:shortcut={{shift: true, code: 'Digit1'}} on:click={() => buttonCount++}>
	Triggers a click on the button (Shift + 1)				
</button>

Clicked: {buttonCount}

Future actions considering adding

You can vote for or discuss proposed actions:

  • closeOnEscape/closeOnScroll/closeOnFocusOutside: sveltejs/rfcs#24 (comment)
  • selectTextOnFocus/clearTextOnEscape
  • blurOnEscape/blurOnEnter
  • viewport: creates enterViewport/leaveViewport events sveltejs/rfcs#24 (comment)
  • activeLink: adds a class if the current link is "active" #13 (comment)
  • focus as a JS version of autofocus HTML attribute #22

Click to vote:

Propose a new action here!