fractils

Some stuff I often use...

pnpm i -D fractils

utils

device

stores

A series of device related stores.
store
mobile
Detects if screenW < mobileThreshold
store
mobileThreshold
Writable store to adjust the $mobile 'breakpoint' threshold. Default 900
store
screenW
Tracks the screen width.
store
screenH
Tracks the screen height.
store
scrollY
Tracks the users scroll position.
store
mouse
Tracks the users mouse position.
First, the stores need to be registered. Β Ideally in the root layout:

src/routes/__layout.svelte
<script>
	import { Device } from 'fractils'
</script>

<Device />
↓

Now, they're reactive:

Example.svelte
<script>
	import { mobileThreshold, mobile, screenH, screenW, scrollY } from 'fractils'

	$mobileThreshold = 1000
</script>

mobile: {$mobile}
screenH: {$screenH}
screenW: {$screenW}
scrollY: {$scrollY}
mouse: {$mouse.x}, {$mouse.y}
↓
mobile
false
screenW
900
screenH
900
scrollY
0
mouse
0, 0
</>

localStorageStore

store

A Svelte store that persists to localStorage.
param
key
The key to store the data under.
param
value
The initial value of the store.
returns
A writable store.
<script>
	import { localStorageStore } from 'fractils'

	const count = localStorageStore('count', 0)
</script>

<div on:click={() => $count++}>+</div>

{$count}

<div on:click={() => $count--}>-</div>
↓
-
+
refresh the page and count will persist </>

log

function

A simple logger that only runs in dev environments.

param
msg
A string or object to log.
param
color
Any CSS color value ( named | hex | rgb | hsl ).
param
bgColor
Same as color ⇧.
param
fontSize
Any number.
param
css
Optional additional CSS.
<script>
	import { log } from 'fractils'

	log('Hello world', 'blue', '#222', 20, 'font-weight: bold;')
</script>
↓
04:20:69.173
Hello world
log.ts:21

β“˜ Β  Add log.ts to devtools ignore list to forward stack traces (It's pretty annoying when you click on a log's link in devtools and it takes you to the logger file instead of the callsite).

</>

wait

function

A simple wait timer.
param
t
Time to wait in ms.
returns
A promise that resolves after t ms.
<script>
	import { wait } from 'fractils'

	let ready, set, go
	async function start() {
		ready = true
		await wait(500)
		set = true
		await wait(500)
		go = true
	}
</script>
↓

ready

set

go

</>

mapRange

function

Maps a value from one range to another.
param
value
The value to map.
param
x1
Lower bound of the input range.
param
x2
Upper bound of the input range.
param
y1
Lower bound of the output range.
param
y2
Upper bound of the output range.
returns
A number mapped from the input range to the output range
<script>
	import { mapRange } from 'fractils'
	
	let value = 50
    $: valueMapped = mapRange(value, 0, 100, -10, 10)
</script>

{value}

<input bind:value type='range'/>

{valueMapped}
↓
50
0.00
</>

clamp

function

Clamps a value between a minimum and maximum.
param
value
The value to clamp.
param
min
The minimum return value.
param
max
The maximum return value.
returns
The value clamped between the minimum and maximum.
<script>
	import { clamp } from 'fractils'

	$: value = clamp(value ?? 50, 25, 75)
</script>

{value}

<input bind:value type='range'/>
↓
50
</>

theme

ThemeToggle

component

A simple component to toggle between light and dark theme.
prop
init
Make false to prevent initTheme() from being called when the component mounts. Defaults to true.
<script>
	import { ThemeToggle } from 'fractils'
</script>

<ThemeToggle />
↓
</>

theme

store + functions

A series of utilitites for managing the active theme. <ThemeToggle /> component manages all of this by default.
store
theme
A writable, persistant store to manage the active theme.
function
initTheme
Initializes theme from system preference or theme store and registers a prefers-media listener for changes.
note: <ThemeToggle /> component does this for you.
<script>
	import { theme, initTheme } from 'fractils'
	import { onMount } from 'svelte'

	onMount(() => initTheme())
</script>

{$theme}
↓

function
toggleTheme
Toggles $theme to and from light and dark mode.
function
applyTheme
Manually apply a specific theme.
param
newTheme
The theme to apply.

<script>
	import { toggleTheme, applyTheme } from 'fractils'
</script>

<button on:click={() => applyTheme("light")}> Light </button>
<button on:click={toggleTheme}> Toggle </button>
<button on:click={() => applyTheme("dark")}> Dark </button>
↓
</>

actions

clickOutside

action

Emits an event when the user clicks outside the element. Great for modals.
param
whitelist
Array of classnames. If the click target element has one of these classes, it will not be considered an outclick.
event
outclick
Fired when the user clicks outside of the element.
detail
target
The element that was clicked. Access with e.detail.target
<script lang="ts">
	import { clickOutside } from 'fractils'

	let clickedOutside

	function handleClickOutside(e: CustomEvent) {
		clickedOutside = true
		console.log(e.detail.target) // the element that was clicked
	}
</script>

<div
	use:clickOutside="{{ whitelist: ['notme'] }}"
	on:outclick="{handleClickOutside}"
>
	clickedOutside = {clickedOutside}
</div>

<div class="notme">🚫</div>
↓
clickedOutside = false
🚫
</>

visibility

action

Observes an element's current viewport visibility and dispatches relevant events.
param
options
Optional config:
option
view
The root view. Defaults to `window`.
option
margin
Margin around root view - 'px' or '%'. Default '0px'.
option
threshold
% of pixels required in view to trigger event. An array will trigger multiple events - '0-1'. Default 0.
option
once
Whether to dispatch events only once. Default false.
event
v-change
Triggered when the element enters or exits view.
event
v-enter
Triggered when the element enters view.
event
v-exit
Triggered when the element exits view.
event
detail
boolean
isVisible
True if the element is currently in the viewport.
element
entry
The element being observed.
object
scrollDirection
The direction of the scroll. scrollDirection.vertical and scrollDirection.horizonal will be either 'up', 'down', 'left', or 'right'.
<script>
	import { bounceOut } from 'svelte/easing'
	import { fly } from 'svelte/transition'
	import { visibility } from 'fractils'
	
	let visible, scrollDir, options = { threshold: 0.75 }

	function handleChange(e) {
		visible = e.detail.isVisible
		scrollDir = e.detail.scrollDirection
	}
</script>

<div use:visibility={options} on:v-change={handleChange}>
	{#if visible}
		<div in:fly={{ y: -20, easing: bounceOut }}>
			going {scrollDir === 'down' ? '⬇' : '⬆'}
		</div>
	{/if}
</div>
↓
</>

components

Tooltip

component

A thin Svelte wrapper around the tippy.js library for easy tooltips.
prop
content
Text content of the tooltip.
prop
placement
top | right | bottom | left.
prop
delay
Intro & outro delay in ms. Default [500, 100].
prop
offset
X and Y offset in px. Default [10, 0].
prop
arrow
Whether to show the arrow connecting the tooltip to the target.
prop
interactive
Whether the tooltip should be interactive.
prop
display
none | contents
prop
instance
The tippy instance in case you need to access it.
<script>
	import { Tooltip } from 'fractils'
</script>

<Tooltip content="Thanks!">
	<div class="hover-1"> Hover over me! </div>
</Tooltip>
↓
Hover over me!
</>

OnMount

component

Mounts an element on Svelte's onMount lifecycle hook . Often used to force a svelte transition to play on page-load.
<script>
	import { OnMount } from 'fractils'
</script>

<OnMount>
	<div in:fly={{ x: 100, duration: 1000 }}>
		My intro transition will always play!
	</div>
</OnMount>
↓
</>

MacScrollbar

component

Replaces the default scrollbar with a MacOS-style scrolbar.

You probably shouldn't use this for anything that needs to be accessible (most things).
string
root
The root element used to scroll. Defaults to body, but it can be replaced with HTMLElement or query selector.

src/routes/__layout.svelte
<script>
    import { MacScrollbar } from 'fractils'
</script>

<MacScrollbar />
↓
You can see it when you scroll on this page ->
</>