├── .gitignore ├── README.md ├── package.json ├── rollup.config.js ├── src ├── actions │ └── autoresize.js ├── components │ ├── Button.svelte │ └── Input.svelte ├── index.svelte └── stores │ ├── errors.js │ ├── touched.js │ └── values.js └── svelte.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | yarn.lock 4 | package-lock.json 5 | index.js 6 | index.mjs -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # svelte-easyforms 2 | 3 | A very opinionated form library for Svelte. Currently only supports inputs and textarea. 4 | 5 | [DEMO](https://svelte.dev/repl/d133210432dc47758674ac6a9233e370?version=3.16.0) 6 | 7 | Usage: 8 | 9 | ```javascript 10 | import Form from "svelte-easyforms"; 11 | 12 | const emailValidator = value => 13 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( 14 | value 15 | ); 16 | 17 | const inputs = [ 18 | { 19 | name: "name", 20 | title: "Who are you ?", 21 | placeholder: "Name, company, etc..." 22 | }, 23 | { 24 | name: "email", 25 | title: "What's your email?", 26 | placeholder: "Email...", 27 | type: "email", 28 | validator: emailValidator 29 | }, 30 | { 31 | name: "message", 32 | title: "Your message", 33 | placeholder: "Write your message here...", 34 | full: true, 35 | multiline: true 36 | } 37 | ]; 38 | 39 | const submitForm = e => { 40 | console.log("submitForm"); 41 | }; 42 | ``` 43 | 44 | And your HTML: 45 | 46 | ```javascript 47 |
48 | ``` 49 | 50 | Options: 51 | Each input object takes a couple of options 52 | 53 | - name 54 | - initialValue 55 | - title (shows up above the input) 56 | - placeholder 57 | - type (defaults to "text") 58 | - validator (optional, should return true if the value passes) 59 | - multiline (optional, turns input into textarea) 60 | - full (optional, makes the field span the whole form, instead of half) 61 | - errorMessage (optional, shows up if there is an error) 62 | - textareaHeight (optional, used with multiline, specifies how large the textarea field should be to begin with) 63 | - font (optional, specifies font) 64 | 65 | The Form itself takes a number of props: 66 | 67 | - inputs (an array of inputs) 68 | - buttonText (optional) 69 | - reset (optional, makes the resetbutton appear) 70 | - resetText (optional, changes the text on the reset button) 71 | - debug (optional, displays the values, touched and errors objects) 72 | 73 | ## TODO 74 | 75 | - [ ] Add custom input functionality 76 | - [ ] Add other types of form elements like radio buttons and checkboxes 77 | - [ ] Add possibility to pass in more than one validator per input 78 | - [ ] Make buttons slottable in order to let consumers pass in their own buttons 79 | - [ ] Make styling more dynamic 80 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-easyforms", 3 | "version": "1.0.6", 4 | "svelte": "src/index.svelte", 5 | "module": "index.mjs", 6 | "main": "index.js", 7 | "repository": "https://github.com/kevmodrome/svelte-easyforms", 8 | "scripts": { 9 | "build": "rollup -c", 10 | "prepublishOnly": "npm run build" 11 | }, 12 | "devDependencies": { 13 | "rollup": "^1.11.0", 14 | "rollup-plugin-node-resolve": "^4.0.0", 15 | "rollup-plugin-svelte": "^5.0.0", 16 | "svelte": "^3.16.0", 17 | "svelte-preprocess": "^3.2.6" 18 | }, 19 | "keywords": [ 20 | "svelte" 21 | ], 22 | "files": [ 23 | "src", 24 | "index.mjs", 25 | "index.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import svelte from "rollup-plugin-svelte"; 2 | import resolve from "rollup-plugin-node-resolve"; 3 | import pkg from "./package.json"; 4 | 5 | import sveltePreprocess from "svelte-preprocess"; 6 | 7 | const name = pkg.name 8 | .replace(/^(@\S+\/)?(svelte-)?(\S+)/, "$3") 9 | .replace(/^\w/, m => m.toUpperCase()) 10 | .replace(/-\w/g, m => m[1].toUpperCase()); 11 | 12 | export default { 13 | input: "src/index.svelte", 14 | output: [ 15 | { file: pkg.module, format: "es" }, 16 | { file: pkg.main, format: "umd", name } 17 | ], 18 | plugins: [svelte({ preprocess: [sveltePreprocess()] }), resolve()] 19 | }; 20 | -------------------------------------------------------------------------------- /src/actions/autoresize.js: -------------------------------------------------------------------------------- 1 | export function autoresize(node) { 2 | const div = document.createElement("div"); 3 | div.style.display = "block"; 4 | div.style.position = "relative"; 5 | 6 | const sizer = document.createElement("div"); 7 | const style = getComputedStyle(node); 8 | Object.assign(sizer.style, { 9 | fontFamily: style.fontFamily, 10 | fontSize: style.fontSize, 11 | paddingTop: style.paddingTop, 12 | paddingLeft: style.paddingLeft, 13 | paddingBottom: style.paddingBottom, 14 | paddingRight: style.paddingRight, 15 | borderTopWidth: style.borderTopWidth, 16 | borderLeftWidth: style.borderLeftWidth, 17 | borderBottomWidth: style.borderBottomWidth, 18 | borderRightWidth: style.borderRightWidth, 19 | borderTopStyle: style.borderTopStyle, 20 | borderLeftStyle: style.borderLeftStyle, 21 | borderBottomStyle: style.borderBottomStyle, 22 | borderRightStyle: style.borderRightStyle, 23 | lineHeight: style.lineHeight, 24 | boxSizing: style.boxSizing, 25 | position: "relative", 26 | whiteSpace: "pre", 27 | visibility: "hidden" 28 | }); 29 | 30 | Object.assign(node.style, { 31 | position: "absolute", 32 | left: 0, 33 | top: 0, 34 | width: "100%", 35 | height: "100%", 36 | resize: "none" 37 | }); 38 | 39 | div.appendChild(sizer); 40 | node.parentNode.insertBefore(div, node); 41 | div.appendChild(node); 42 | 43 | function handleChange() { 44 | sizer.innerHTML = node.value + " "; 45 | } 46 | 47 | handleChange(); 48 | node.addEventListener("input", handleChange); 49 | 50 | return { 51 | destroy() { 52 | node.removeEventListener("input", handleChange); 53 | } 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/components/Button.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 | 37 | 38 | 45 | -------------------------------------------------------------------------------- /src/components/Input.svelte: -------------------------------------------------------------------------------- 1 | 37 | 38 | 73 | 74 |