npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

formakase

v0.0.1

Published

Forms that work with you

Downloads

3

Readme

Formakase

With there being so many different small details that come with building forms, writing code for it is was rather complex and verbose. Formakase takes care of the things we tend to forget.

Features

  • Minimal code for minimal needs
  • All state handled internally (Think traditional form submissions to a backend where all you need is a "name" attribute)
  • Submit buttons automatically get disabled on form submit
  • Normalization: Strings get trimmed upon submit
  • You have full control over how your form looks like

Most basic form

<template>
  <Formakase @submit="onSubmit">
    <input name="username" />
    <input type="submit"/>
  </Formakase>
</template>

<script>
export default {
  methods: {
    onSubmit(draft) {
      alert(draft) // 👈 { username: '<current input value trimmed>' }
    }
  }
}
</script>

Form with draft access in template (using v-slot)

<template>
  <Formakase @submit="onSubmit" v-slot="form">
    <input name="username" />
    <div>Username: {{ form.draft.username }}</div>
    <input type="submit"/>
  </Formakase>
</template>

<script>
export default {
  methods: {
    onSubmit(draft) {
      alert(draft)
    }
  }
}
</script>

Form with draft access everywhere + mutate form state (using v-model)

<template>
  <Formakase @submit="onSubmit" v-model="form">
    <input name="username" />
    <div>Username: {{ form.draft.username }}</div>
    <input type="submit"/>
  </Formakase>
</template>

<script>
export default {
  data() {
    return { form: {} }
  },
  methods: {
    onSubmit(draft) {
      console.log(draft, this.form)
    }
  }
}
</script>

Specifying default values

Use data-value over value. Specifying "v-bind:value" without "@input" would not make it possible to edit text. The text inside data-value will be placed in the input only upon mounting. Make sure you have all data you need at that point.

<template>
  <Formakase v-slot="form">
    <input type="text" data-value="default value" />
  </Formakase>
</template>

Disabling on submit

Formakase automatically disables submit buttons while the submission is pending. If you want to handle it yourself, you can set autoDisable to false and check form.pending:

<template>
  <Formakase v-slot="form" :autoDisable="false">
    <input type="submit" :disabled="form.pending"/>
  </Formakase>
</template>

To disable all inputs, wrap them in <fieldset :disabled="form.pending">

Normalization

On submission, all strings will automatically get trimmed and updated in the form. You can disable it like this:

<template>
  <Formakase :normalize="false">
  </Formakase>
</template>

Validation

Most things form libraries validate are already supported natively. I recommend you learning about the various input attributes such as type, minlength, min, max, maxlength, required and pattern.

Validate live or on submit

By default, inputs will be validated on submit.

<template>
  <Formakase @submit="onSubmit">
    <input name="username" required />
    <input type="submit"/>
  </Formakase>
</template>

Use the live prop to validate on every input.

<template>
  <Formakase live @submit="onSubmit">
    <input name="username" required />
    <input type="submit"/>
  </Formakase>
</template>

Validation messages

Access errors using form.errors. The messages come directly from the browser (same as with HTML5 form validation).

<template>
  <Formakase @submit="onSubmit" v-slot="form">
    <input name="username" required />
    {{ form.errors.username }}
    <input type="submit"/>
  </Formakase>
</template>

However, you can provide alternative messages.

<template>
  <Formakase :messages="messages">
    <input name="username" requried minlength="3" />
    <input type="submit" />
  </Formakase>
</template>

<script>
export default {
  computed: {
    messages() {
      return {
        tooShort: 'This is too short!' // 👈 define message as a string
        valueMissing(element) { // 👈 or as a function
          return `Field ${element.name} is required!`
        },
      }
    }
  }
}
</script>

For the available keys, see the documentation for validityState.

Custom validations

If you need something more complex, pass a custom validate method.

<template>
  <Formakase @validate="validate">
    <input name="username" />
    <input type="submit"/>
  </Formakase>
</template>

<script>
export default {
  methods: {
    async validate(draft, blame) { // 👈 Support for async/await
      if (draft.username === 'something-bad') {
        blame('username', 'Dont write something bad!')
      }
    }
  }
}
</script>