Skip to main content

Svelte

@tremolo-ui/svelte has the same components as @tremolo-ui/react, with the same parts, props, data-* attributes and theme. Each component page shows the Svelte version of its example under the Svelte tab. This page covers what is written differently.

It needs Svelte 5.40 or later.

npm install @tremolo-ui/svelte

Components​

A component is a set of parts under one name, written with a dot:

<script lang="ts">
import { Knob } from '@tremolo-ui/svelte'

let value = $state(50)
</script>

<Knob.Root bind:value min={0} max={100}>
<Knob.SVGRoot>
<Knob.InactiveLine />
<Knob.ActiveLine />
<Knob.Thumb />
</Knob.SVGRoot>
</Knob.Root>

What differs from React:

ReactSvelte
The valuevalue + onChangebind:value, or value + onChange
A classclassNameclass
Read-onlyreadOnlyreadonly
A stylean objecta string, as for any element
The elementrefbind:ref
Methods (focus, playNote, …)through actionsRefthrough bind:this
Content given as a function (Piano's label)a function returning JSXa snippet
A part of your ownuseKnobContext(selector)useKnobContext(), whose fields follow the value

Actions​

The React hooks that attach an interaction to an element are actions here. They take the options of the matching function in @tremolo-ui/dom, and changing the options does not interrupt a drag in progress.

ReactSvelteOptions
useDraguse:dragcreateDrag
useDragValueuse:dragValuecreateDragValue
useWheeluse:wheelcreateWheel
useLongPressuse:longPresscreateLongPress
useDropZoneuse:dropZonecreateDropZone
<script lang="ts">
import { relativeMapping } from '@tremolo-ui/dom'
import { dragValue } from '@tremolo-ui/svelte'

let value = $state(50)
</script>

<div
use:dragValue={{
axis: { min: 0, max: 100 },
mapping: relativeMapping({ pixelRange: 200 }),
getValue: () => [value, value],
onChange: ([x]) => (value = x),
}}
>
{value}
</div>

MIDI​

useMIDIAccess, useMIDIInput and useMIDIMessage are called while a component initialises. What can change is passed as a function, so that it is read reactively:

<script lang="ts">
import { useMIDIAccess, useMIDIInput } from '@tremolo-ui/svelte'

const midi = useMIDIAccess(false)
useMIDIInput(
() => midi.midiAccess,
() => ({ onNoteOnEvent: (note, velocity) => play(note, velocity) }),
)
</script>

<button onclick={() => midi.request()}>Connect MIDI</button>

Storybook​

The Svelte components have a Storybook of their own.