Helpers and actions
Not everything in the package is a component. These are the functions and actions the components use on each other, exported because they are just as useful in your own code.
Every type mentioned here is written out on the types page.
cn
Merges class names through clsx and tailwind-merge. The second half is
the important one: cn('px-2', 'px-8') gives you px-8 rather than two fighting
utilities. Every component runs its class prop through this, which is why passing a class
always wins.
import { cn } from '@joshicodes/cock';
// Later Tailwind utilities win, so a caller's class beats the default.
cn('px-3 py-2 text-sm', props.class);
cn('rounded-md', isActive && 'bg-accent text-accent-fg');uid
A counter, not a UUID. It exists for wiring aria-describedby and for attributes together when a component renders several elements that have to refer
to each other.
const id = uid(); // ck-1f
const id = uid('field'); // field-1g
<label for={id}>Email</label>
<input {id} aria-describedby="{id}-hint" />Ids are per page load, so do not put one in a database or a URL. In a server-rendered page the counter starts again on the client; the components only use ids for attributes that are set on the same render, where that does not matter.
lockScroll
Freezes the page behind an overlay and pads the body by the scrollbar width, so the layout does not jump sideways. Reference counted: two open overlays take two locks, and scrolling comes back when the last one lets go.
const release = lockScroll();
// …while the overlay is open
release();confetti
A canvas burst, drawn in the theme's accent and status colours unless you pass your own. It returns a promise that resolves when the last piece has faded, and it does nothing at all when the visitor has reduced motion turned on — so you can call it without a guard.
Or press Ctrl+Shift+C, which is wired up further down this page with onHotkey.
confetti(); // from the middle of the screen
confetti({ origin: button }); // from an element
confetti({ origin: { x: 100, y: 400 } }); // from a point
confetti({
count: 220,
angle: -70,
spread: 50,
velocity: 16,
gravity: 0.8,
scale: 1.4,
colors: ['#f0b429', '#e8590c'],
duration: 3200
});ConfettiOptions has the full list. angle is the middle of the cone in degrees, where -90 is straight up and 0 is to the right; gravity and scale are multipliers on the
defaults, so 0.5 is half as heavy and half as big.
onHotkey, matchesHotkey, formatHotkey
Shortcuts written as strings: mod+k, shift+/, alt+enter. mod is ⌘ on Apple devices and Ctrl everywhere else, which is
the part everybody gets wrong. onHotkey listens on the window and returns its own cleanup; formatHotkey gives you the label to print, like the Ctrl+K on the command palette.
const off = onHotkey('mod+k', () => (open = true));
onDestroy(off);
formatHotkey('mod+k'); // ⌘K on Apple devices, Ctrl+K elsewhere
matchesHotkey(event, 'shift+/');Actions
Four Svelte actions, used by the overlays and exported for your own. portal moves a node
to <body> so no ancestor can clip it, clickOutside closes things, trapFocus keeps Tab inside a dialog and hands focus back on destroy, and anchored positions a panel against a trigger and flips it when the viewport runs out.
<div use:portal>…</div> <!-- moved to <body> -->
<div use:portal={'#overlays'}>…</div>
<div use:clickOutside={() => (open = false)}>…</div>
<div use:clickOutside={{ handler: close, ignore: [trigger] }}>…</div>
<div use:trapFocus>…</div>
<div use:anchored={{ to: trigger, placement: 'bottom-start', offset: 8 }}>…</div>trapFocus needs something to focus
Style fragments
Four strings of Tailwind utilities — focusRing, focusRingInset, disabled and transition — that every component in the kit uses. Reach for
them when you write a control of your own and want it to ring and fade like the rest.
import { cn, focusRing, transition, disabled } from '@joshicodes/cock';
<button class={cn('rounded-md px-3 py-2', focusRing, transition, disabled)}>Documented elsewhere
themeandaccents— the runtime theme object, on theming.toastandtoasts— on Toaster.themeScript,themeScriptTagandthemeHandle— the no-flash script, in getting started.