# drawably Hand-drawn UI controls. Every mount generates a fresh pen sketch from seeded randomness, and the stroke boils like an animated doodle. Zero dependencies, ~9 KB of JS gzipped (React wrappers add under 1 KB) and a 3 KB stylesheet. An optional pen font is a separate 31 KB. ![Buttons, checkbox, radio and toggle drawn in a boiling pen stroke](assets/demo.svg) ## Install ```sh npm i drawably ``` ## Quick start ```js import { drawablyButton } from "drawably"; import "drawably/style.css"; drawablyButton(document.querySelector("#done"), { variant: "solid" }); ``` React: ```jsx import { DrawablyButton } from "drawably/react"; import "drawably/style.css"; Done ``` Each attach call returns a sketch handle: ```js const sketch = drawablyButton(el); sketch.resketch(); // redraw with a new random seed sketch.resketch(42); // redraw with a specific seed sketch.destroy(); // remove the SVG and all listeners ``` ## Buttons Three variants: `outline` (default), `solid`, `scribble`. Buttons also carry a state machine for async work: ![The four button states: idle, loading, error, success](assets/states.svg) ```js const button = drawablyButton(el); button.setState("loading"); // dims the button, boils faster button.setState("error"); // redraws in red button.setState("success"); // redraws in green button.setState("idle"); ``` In React, pass the `state` prop; the sketch stays put and only the state changes: ```jsx Save ``` Override the state colours with `--drawably-error` and `--drawably-success`. For secondary or destructive actions, set `tone: "neutral"` (warm grey) or `tone: "danger"` (red). ## Controls | Function | Element it expects | | --- | --- | | `drawablyButton(el, opts)` | a `