Svelte Component Organisation
Svelte components can get big pretty quickly, in terms of line count. With interactivity that’s closely tied to DOM elements, such as drag and drop functionality, it can be hard to pull chunks of code out into separate utility functions without creating a large API surface between the component and the utility.
It’s also easy to get sloppy with names. I often find myself with similarly-named functions for event handlers and functions that do related stuff. React solved an adjacent problem with the standard event name scheme – object; “did”/“will”; verb.
I’ve recently been playing with a system of organising Svelte components with standard namespace-style variables in the script section. These are all objects. The ones I currently have are:
refs
Starts as an empty object. All
bind:this
refs go here. Having this as an object means you don’t have to initialise dedicated variables for all your bindings – just store each one with a unique key in the object.appState
UI state that’s relevant to business logic as opposed to just UI implementation details. Examples:
mode
- current editing mode for a table editor component.
appFunctions
Business logic
uiState
UI state that is just implementation details. Examples:
lastEventDetails
for keeping track of what caused e.g. a blur event;colDropMarkerHeight
for styling a drag and drop hint.
domHandlers
Functions that directly handle DOM events, ie. they are passed to
on:
attributes.uiHelpers
Functions called from the HTML to do some calculation. Examples:
<div style={cellStyle(table, cell)}>
uiQueryFunctions
Functions that query the DOM for some value/size/etc. Examples:
- Using
document.activeElement
to get the object associated with the currently focused element
- Using