34 |
35 |
36 |
37 |
44 |
--------------------------------------------------------------------------------
/src/lib/Checkbox/Checkbox.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 | {#each values as value}
11 |
12 |
13 | {/each}
--------------------------------------------------------------------------------
/src/lib/FastForm/FastForm.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Canvas, Meta, Story } from '@storybook/addon-docs';
2 | import FastForm from './FastForm.svelte'
3 |
4 |
5 |
6 |
7 | # FastForm
8 |
9 | `` is a necessary component that eases the process of creating a form. The event handlers are passed down as props within the `FastForm` component.
10 |
11 | ### Getting Started/Using FastForm Component
12 |
13 | 1.Declare your `` component within your markup section of your current component
14 |
15 | 2.Add initValues, handleSubmit, and validators as functions within the props of ``
16 | (You can declare the functions within the script tag or inline)
17 |
18 | ### Example
19 | ```jsx
20 |
37 |
38 | // Setting your FastForm component in the markup section with children
39 |
40 | // The children of FastForm would be placed here
41 |
42 | ```
43 |
44 |
45 | ### Props
46 |
47 | | Name | Required| Type | Default | Description |
48 | |------|:-------:|------| :-----: |-------------|
49 | |initValues| No |Object | - | Object that declares the inital values of the Fields as [name:value] pairs
50 | |handleSubmit| No | Function| - | Function that defines what the form will do onSubmit. It takes one input which will be form state. Form state is a object which contains two objects labeled: values and errors.
51 | |handleChange| No | Function| - | Function that defines what the form will do onChange. It takes one input which will be form state. Form state is a object which contains two objects labeled: values and errors.
52 | |validate| No | Function | - | [Validation page](?path=/docs/validators-validators--page)
--------------------------------------------------------------------------------
/src/lib/FastForm/FastForm.stories.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
18 |
19 |
20 |
21 | {
23 | args.nameRequired ? required('name') : null
24 | args.emailsMustMatch ? mustMatch('confirmEmail', 'email') : null
25 | minNumOptions('icecream', args.minIcecreamChoices)
26 | maxNumOptions('icecream', args.maxIcecreamChoices)
27 | }}
28 | handleSubmit={({values, errors}) => {
29 | myValues = values
30 | myErrors = errors
31 | }}
32 | >
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
{JSON.stringify(myValues, null, 2)}
42 |
{JSON.stringify(myErrors, null, 2)}
43 |
44 |
45 |
46 |
62 |
--------------------------------------------------------------------------------
/src/lib/FastForm/FastForm.svelte:
--------------------------------------------------------------------------------
1 |
34 |
35 |
38 |
--------------------------------------------------------------------------------
/src/lib/Field/Field.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Canvas, Meta, Story } from '@storybook/addon-docs';
2 |
3 | import Field from './Field.svelte'
4 | import FastForm from '../FastForm/FastForm.svelte'
5 |
6 |
7 |
8 | # Field
9 |
10 |
11 |
12 | ## Before we begin
13 | `` is meant for selecting input types. The type of input must be specified, and you really need to wrap this within `` in order for us to manage your state.
14 |
15 | You have been warned!
16 | Please refer to the following documentations that may help you write the `` component.
17 | - [FastForm documentation](?path=/story/fastform-fastform--page)
18 | - [How to write validations](?path=/story/validators-validators--page)
19 |
20 | ## How to use ``
21 |
22 | `` component is like an `` field, it can take in any props, (class, id etc). In addition, table specifies the required and other fields that's unique to `` component
23 |
24 | | Name | Required | Type | Default | Description |
25 | | --- | --- | --- | --- | --- |
26 | | **name** | **Yes** | String | - | Name for the is specific field |
27 | | **type** | **Yes** | String | - | Specify the type of input field |
28 | | **values** | **Yes*** | Array | - | Values required for specific components. *See Types of Field Table for special types
29 | | **handleBlur** | No | Function | - | Instructions to be run onBlur, this function takes in an object that contains *`values`*, and *`errors`* object, and will trigger after validate function |
30 | | **handleChange** | No | Function | - | Instructions to be run OnChange, this function takes in an object that contains *`values`*, and *`errors`* object, and will trigger after validate function|
31 | | **validate** | No | Function | - | Any validators that is required to validate the *``* component. Refer to validator docs on how to write your own validations|
32 | | **validateOnBlur** | No | Boolean | `true` | Passed in validate function will run onBlur|
33 | | **validateOnChange** | No | Boolean | `!validateOnBlur` | Passed in validate function will run onChange |
34 |
35 |
36 | ## Types of Field
37 |
38 | The types of the input field needs to be passed in to the `type` prop. You can pass it in like how you would specify in an HTML `` field. But there are some special cases.
39 |
40 | | Types | Values Type | Example |
41 | | --- | --- | --- |
42 | | Regular types | - | ``|
43 | | [multiselect](?path=/story/field-multi-select--multi-select)** | Array | `` |
44 | | [radio](?path=/story/field-radio--radio)** | Array | `` |
45 | | [select](?path=/story/field-select--select)** | Array | `` |
46 | | [checkbox](?path=/story/field-checkbox--checkbox)** | Array | `` |
47 | ** Special input type that also require `values` prop to be passed in.
48 | ## Examples
49 |
50 | Below is an example of a creating a checkbox component using vanilla Svelte.
51 | ```jsx
52 |
59 |
60 | {#each iceCreamSelection as option}
61 |
62 |
63 | {/each}
64 |
65 | ```
66 |
67 | In comparison, below is an example if you were to write this using FastForm.
68 | ```jsx
69 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | ```
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/src/lib/Field/Field.svelte:
--------------------------------------------------------------------------------
1 |
64 |
65 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/src/lib/Input/Input.stories.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
19 |
20 |
21 |
22 | {
24 | myValues = values
25 | myErrors = errors
26 | }}
27 | >
28 |
29 |
30 |
31 |
32 |
32 |
33 |
--------------------------------------------------------------------------------
/src/lib/validators/required/required.ts:
--------------------------------------------------------------------------------
1 | import type { formStoreValueType } from '../../types'
2 |
3 | export default function required(field : string, store: formStoreValueType) : formStoreValueType {
4 | if (!store.values[field]) {
5 | store.errors[field] ??= {}
6 | store.errors[field].required = `Error: '${field}' is a required field.`
7 | }
8 | return store
9 | }
10 |
--------------------------------------------------------------------------------
/src/lib/validators/validators.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Canvas, Meta, Story } from '@storybook/addon-docs';
2 |
3 |
4 |
5 | # Validators
6 | Validation can happen at both the form-level and field-level. Both our `` and `` components can take in a `validate` prop.
7 | - Form-level - This type of validation runs from the `validate` prop in the `` component. It will trigger directly before `handleSubmit`
8 | - Field-level - This type of validation runs from the `validate` prop in the `` component. It can trigger `onChange`, `onBlur`, or both!
9 |
10 |
11 | ### [`required(name: string)`](?path=/story/validators-required--required)
12 | Indicates that the given field is required.
13 | - `name`: Name of the required field.
14 |
15 | ```jsx
16 |
23 |
24 |
25 |
26 |
27 |
28 | ```
29 |
30 | ### [`mustMatch(name: string, nameToMatch: string)`](?path=/story/validators-mustmatch--must-match)
31 | Indicates that two fields must have the same value.
32 | - `name`: Name of one of the fields (The error will be listed under this label).
33 | - `nametoMatch`: Name of the other field.
34 | ```jsx
35 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | ```
49 |
50 | ### [`minNumOptions(name: string, min: number)`](?path=/story/validators-minnumoptions--min-num-options)
51 | For fields that can have multiple selected values (i.e. checkboxes), this validator determines the minimum number of options that the user must fill out.
52 | - `name`: Name of the field.
53 | - `min`: Minimum number of selected options.
54 |
55 | ```jsx
56 |
63 |
64 |
65 |
66 |
67 | ```
68 | ### [`maxNumOptions(name: string, max: number)`](?path=/story/validators-maxnumoptions--max-num-options)
69 | For fields that can have multiple selected values (i.e. checkboxes), this validator determines the maximum number of options that the user can fill out.
70 | - `name`: Name of the field.
71 | - `max`: Maximum number of selected options.
72 |
73 | ```jsx
74 |
81 |
82 |
83 |
84 |
85 | ```
86 | ### `customValidator(validator: ({values, errors}) => {values, errors})`
87 | The custom validator is for any validation that cannnot be handled by the prewritten validation functions.
88 | - `validator`: A function that will have an object with `values` and `errors` as properties be passed in as an argument. These objects can be mutated during the function to add errors to the `errors` object. The function must return these objects.
89 |
90 | ```jsx
91 |
103 |
104 |
105 |
106 |
107 | ```
--------------------------------------------------------------------------------
/src/lib/validators/verifyEmail/verifyEmail.stories.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
16 |
17 |
18 | {
20 | myValues = values
21 | myErrors = errors
22 | }}
23 | validate={({verifyEmail}) => {
24 | verifyEmail('email', args.repeatEmail)
25 | }}>
26 |
27 |
28 |
29 |
30 |
46 |
--------------------------------------------------------------------------------
/src/stories/Getting Started/GettingStarted.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Canvas, Meta, Story } from '@storybook/addon-docs';
2 | import gif from '../../../fastform-demo.gif'
3 |
4 |
5 |
6 |
7 | # Getting Started
8 |
9 | FastForm is a form component library designed specifically for Svelte that includes different base components and various validator logic. FastForm's components come with no styling to allow developers more customization over the look of their applications.
10 |
11 | FastForm is available as an [npm package](https://www.npmjs.com/package/@fastform/form). You can install it by running the following command in the terminal within your project directory:
12 |
13 | ## Installation and Imports
14 | You can import FastForm onto your application using the following command.
15 | ```bash
16 | npm install @fastform/form
17 | ```
18 | Example for the [Field](?path=/docs/field-field--page) component:
19 | ```jsx
20 | import { FastForm, Field } from '@fastform/form';
21 | ```
22 |
23 | ## How It Works
24 |
25 | FastForm comes with a store along with predefined validators. Developers have the ability to create their own custom validator functions to pass onto components. Refer to the [Validators](?path=/docs/validators-validators--page) section for more details on each validator.
26 |
27 | Here is how FastForm works:
28 |
29 |
30 | In this demo, both the value and errors object is displayed below the fields. We can see the following occurred:
31 |
32 | * The first name field was left blank, which triggered an error for the ['required'](?path=/story/validators-required--required) validator.
33 | * The first name field did not match our other name field with name 'John Doe', triggering an error for the ['mustMatch'](?path=/story/validators-mustmatch--must-match) validator.
34 | * No options were checked for the ice cream field, triggering an error for the ['minNumOptions'](?path=/story/validators-minnumoptions--min-num-options) validator.
35 |
36 | Once each validator's conditions were met, the errors were cleared.
37 |
38 | In the code snippet below, our [Field](?path=/story/field-field--page) components for both names and icecream are within our [FastForm](?path=/story/fastform-fastform--page) component. FastForm takes in initial values, a handleSubmit function, and validator functions.
39 |
40 | We can see the mustMatch validator is being passed onto both name fields, the minNumOptions validator on the icecream field, and the required validator on the first name field. More details on the components and validators can be found in the examples.
41 |
42 | ```jsx
43 | {
47 | mustMatch('name', 'name2')
48 | minNumOptions('icecream', 1)
49 | required('name')
50 | }}>
51 |
52 |
53 |
54 |
55 |
56 | ```
--------------------------------------------------------------------------------
/src/stories/More Information/Changelog.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
4 |
5 | # v0.3.2 - Form-level onChange
6 | #### August 5, 2022
7 | ---
8 | - Implemented a `handleChange` prop to FastForm
9 |
10 |
11 |
12 | # v0.3.0 - Release!
13 | #### August 4, 2022
14 | ---
15 | This version marks the release of FastForm!
16 | Information about FastForm can be found [here](https://www.npmjs.com/package/@fastform/form)!
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/stories/More Information/Contributors.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Canvas, Meta, Story } from '@storybook/addon-docs';
2 |
3 |
4 |
5 | # Contributors
6 |
7 | The following individuals are contributors to FastForm. For any future updates, please add additional contributors.
8 |
9 | * Angel Cortes Gildo - [LinkedIn](https://www.linkedin.com/in/angel-cortes-gildo-708972243/) / [Github](https://github.com/angcortes)
10 | * Griffin Barlow - [LinkedIn](https://www.linkedin.com/in/griffinbrlw/) / [Github](https://github.com/griffin104)
11 | * Ilija Bibic - [LinkedIn](https://www.linkedin.com/in/ilija-bibic/) / [Github](https://github.com/ibibic)
12 | * Steven Yuan - [LinkedIn](https://www.linkedin.com/in/steven-yuann/) / [Github](https://github.com/steven-yuann)
13 |
--------------------------------------------------------------------------------
/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-auto'
2 | import preprocess from 'svelte-preprocess'
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | preprocess: preprocess(),
7 | kit: {
8 | package: {
9 | exports: () => false
10 | },
11 | adapter: adapter()
12 | }
13 | }
14 |
15 | export default config
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "noImplicitAny": true,
5 | "esModuleInterop": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "moduleResolution": "node",
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true,
12 | },
13 | "include": ["src/**/*"]
14 | }
15 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { sveltekit } from '@sveltejs/kit/vite'
2 |
3 | /** @type {import('vite').UserConfig} */
4 | const config = {
5 | plugins: [sveltekit()]
6 | }
7 |
8 | export default config
9 |
--------------------------------------------------------------------------------