Skip to content

Commit

Permalink
feat: implement Textarea and Dropdown type
Browse files Browse the repository at this point in the history
  • Loading branch information
raichev-dima committed Dec 17, 2024
1 parent d94d36b commit 9563b12
Show file tree
Hide file tree
Showing 18 changed files with 311 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/formkit/src/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const boxInput = createSection('input', () => ({
}))

/**
* Input definition for a text.
* Input definition for a checkbox.
* @public
*/
export const checkbox: FormKitTypeDefinition = {
Expand Down
4 changes: 4 additions & 0 deletions packages/formkit/src/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { text } from './text'

/**
* Input definition for a color.
* @public
*/
export const color: FormKitTypeDefinition = {
...text,
forceTypeProp: 'color',
Expand Down
2 changes: 1 addition & 1 deletion packages/formkit/src/colorpicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const colorInput = createSection('input', () => ({
}))

/**
* Input definition for a text.
* Input definition for a colorpicker.
* @public
*/
export const colorpicker: FormKitTypeDefinition = {
Expand Down
4 changes: 4 additions & 0 deletions packages/formkit/src/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { text } from './text'

/**
* Input definition for a date.
* @public
*/
export const date: FormKitTypeDefinition = {
...text,
forceTypeProp: 'date',
Expand Down
2 changes: 1 addition & 1 deletion packages/formkit/src/datepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const dateInput = createSection('input', () => ({
}))

/**
* Input definition for a text.
* Input definition for a datepicker.
* @public
*/
export const datepicker: FormKitTypeDefinition = {
Expand Down
56 changes: 56 additions & 0 deletions packages/formkit/src/dropdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { FormKitTypeDefinition } from '@formkit/core'
import { casts, createSection } from '@formkit/inputs'
import { token } from '@formkit/utils'
import { VaSelect } from 'vuestic-ui'
import { createInputWrapper } from './createInputWrapper'
import { vuesticInputs } from './features/vuesticInputs'

const FormKitInputWrapper = createInputWrapper(VaSelect);

const dropdownInput = createSection('input', () => ({
$cmp: 'FormKitInputWrapper',
bind: '$attrs',
props: {
context: '$node.context',
prefixIcon: '$prefixIcon',
suffixIcon: '$suffixIcon'
}
}))

/**
* Input definition for a dropdown.
* @public
*/
export const dropdown: FormKitTypeDefinition = {
/**
* The actual schema of the input, or a function that returns the schema.
*/
schema: dropdownInput(),
/**
* The type of node, can be a list, group, or input.
*/
type: 'input',
/**
* The family of inputs this one belongs too. For example "text" and "email"
* are both part of the "text" family. This is primary used for styling.
*/
family: 'text',
/**
* An array of extra props to accept for this input.
*/
props: [],
/**
* A library of components to provide to the internal input schema
*/
library: {
FormKitInputWrapper,
},
/**
* Additional features that should be added to your input
*/
features: [casts, vuesticInputs],
/**
* The key used to memoize the schema.
*/
schemaMemoKey: token(),
}
4 changes: 4 additions & 0 deletions packages/formkit/src/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { text } from './text'

/**
* Input definition for a email.
* @public
*/
export const email: FormKitTypeDefinition = {
...text,
forceTypeProp: 'email',
Expand Down
20 changes: 4 additions & 16 deletions packages/formkit/src/form.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import { FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { VaForm, VaButton } from 'vuestic-ui'
import { VaForm, VaMessageList } from 'vuestic-ui'
import {
messages,
actions,
createSection,
forms,
disablesChildren,
} from '@formkit/inputs'
import { messages, message } from './sections'
import { submit } from './submit'


export const message = createSection('message', () => ({
$el: 'li',
for: ['message', '$messages'],
attrs: {
style: 'color: var(--va-danger)',
key: '$message.key',
id: `$id + '-' + $message.key`,
'data-message-type': '$message.type',
},
}))

export const formInput = createSection('form', () => ({
$cmp: 'VaForm',
bind: '$attrs',
Expand Down Expand Up @@ -75,8 +63,8 @@ export const form: FormKitTypeDefinition = {
],

library: {
'VaForm': VaForm,
'VaButton': VaButton
VaForm,
VaMessageList,
},
/**
* Additional features that should be added to your input
Expand Down
2 changes: 2 additions & 0 deletions packages/formkit/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { button } from './button'
export { checkbox } from './checkbox'
export { date } from './date'
export { datepicker } from './datepicker'
export { dropdown } from './dropdown'
export { email } from './email'
export { color } from './color'
export { colorpicker } from './colorpicker'
Expand All @@ -12,4 +13,5 @@ export { search } from './search'
export { submit } from './submit'
export { tel } from './tel'
export { text } from './text'
export { textarea } from './textarea'
export { url } from './url'
4 changes: 4 additions & 0 deletions packages/formkit/src/password.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { text } from './text'

/**
* Input definition for a password.
* @public
*/
export const password: FormKitTypeDefinition = {
...text,
forceTypeProp: 'password',
Expand Down
4 changes: 4 additions & 0 deletions packages/formkit/src/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { text } from './text'

/**
* Input definition for a search.
* @public
*/
export const search: FormKitTypeDefinition = {
...text,
forceTypeProp: 'search',
Expand Down
4 changes: 4 additions & 0 deletions packages/formkit/src/submit.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { token } from '@formkit/utils'
import { button } from "./button";

/**
* Input definition for a submit button.
* @public
*/
export const submit = {
...button,
forceTypeProp: 'submit',
Expand Down
4 changes: 4 additions & 0 deletions packages/formkit/src/tel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { text } from './text'

/**
* Input definition for a telephone.
* @public
*/
export const tel: FormKitTypeDefinition = {
...text,
forceTypeProp: 'tel',
Expand Down
60 changes: 60 additions & 0 deletions packages/formkit/src/textarea.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { type FormKitTypeDefinition } from '@formkit/core'
import { casts, createSection } from '@formkit/inputs'
import { token } from '@formkit/utils'
import { VaTextarea } from 'vuestic-ui'
import { vuesticInputs } from './features/vuesticInputs'
import { createInputWrapper } from './createInputWrapper'

const FormKitInputWrapper = createInputWrapper(VaTextarea)

const textareaInput = createSection('input', () => ({
$cmp: 'FormKitInputWrapper',
bind: '$attrs',
props: {
context: '$node.context',
prefixIcon: '$prefixIcon',
suffixIcon: '$suffixIcon'
}
}))

/**
* Input definition for a textarea.
* @public
*/
export const textarea: FormKitTypeDefinition = {
/**
* The actual schema of the input, or a function that returns the schema.
*/
schema: textareaInput(),
/**
* The type of node, can be a list, group, or input.
*/
type: 'input',
/**
* The family of inputs this one belongs too. For example "text" and "email"
* are both part of the "text" family. This is primary used for styling.
*/
family: 'text',
/**
* An array of extra props to accept for this input.
*/
props: [],
/**
* A library of components to provide to the internal input schema
*/
library: {
FormKitInputWrapper
},
/**
* Forces node.props.type to be this explicit value.
*/
forceTypeProp: 'text',
/**
* Additional features that should be added to your input
*/
features: [casts, vuesticInputs],
/**
* The key used to memoize the schema.
*/
schemaMemoKey: token(),
}
4 changes: 4 additions & 0 deletions packages/formkit/src/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type FormKitTypeDefinition } from '@formkit/core'
import { token } from '@formkit/utils'
import { text } from './text'

/**
* Input definition for a url.
* @public
*/
export const url: FormKitTypeDefinition = {
...text,
forceTypeProp: 'url',
Expand Down
31 changes: 31 additions & 0 deletions packages/ui/src/stories/formkit/Dropdown.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { StoryFn } from '@storybook/vue3'
import * as types from '@vuestic/formkit'

export default {
title: 'Formkit Integration/Dropdown',
}

export const Default: StoryFn = () => ({

setup () {
const frameworks = [
{ text: 'React', value: 'react' },
{ text: 'Vue', value: 'vue' },
{ text: 'Angular', value: 'angular' },
{ text: 'Svelte', value: 'svelte' },
]
return {
types,
frameworks,
}
},
template: `
<FormKit
:type="types.dropdown"
name="framework"
label="Choose your favorite frontend framework"
placeholder="Backbone.js"
:options="frameworks"
/>
`,
})
78 changes: 78 additions & 0 deletions packages/ui/src/stories/formkit/Form.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { StoryFn } from '@storybook/vue3'
import * as types from '@vuestic/formkit'
import { ref } from 'vue'
import { VaCollapse } from 'vuestic-ui'

export default {
title: 'Formkit Integration/Form',
}

export const Basic: StoryFn = () => ({
components: {
VaCollapse,
},
setup () {
// NEW: submit handler, which posts to our fake backend.
const submitApp = async (_formData: any, node: any) => {
await new Promise(resolve => setTimeout(resolve, 1400))
node.clearErrors()
alert('Your application was submitted successfully!')
}

const formValue = ref({})

return {
types,
formValue,
submitApp,
}
},
template: `
<h1 class="text-2xl font-bold mb-4">
Carbon Sequestration Grant
</h1>
<FormKit
v-slot="{ state: { loading } }"
v-model="formValue"
:type="types.form"
class="grid grid-cols-1 md:grid-cols-3 gap-6"
:submit-label="loading ? 'Submitting...' : ''"
@submit="submitApp"
>
<div>
<FormKit
:type="types.email"
name="email"
label="*Email address"
validation="required|email"
/>
</div>
<div>
<FormKit
:type="types.text"
name="organization_name"
label="*Organization name"
validation="required|length:3"
/>
</div>
<div>
<FormKit
:type="types.textarea"
name="money_use"
label="*How will you use the money?"
validation="required|length:5,10"
/>
</div>
</FormKit>
<VaCollapse
class="min-w-96 mt-4"
header="Form data"
>
<pre>{{ formValue }}</pre>
</VaCollapse>
`,
})
Loading

0 comments on commit 9563b12

Please sign in to comment.