Skip to content

Commit 8a37759

Browse files
docs: new docs site using vitepress (#2)
* docs: initial documentation * chore: update package * chore: initial netlify.toml * chore: update vitepress style * docs: add social link * docs: add logo * docs: update docs * docs: update docs * docs: rename package * docs: update vitepress config * docs: update vitepress config * docs: update vitepress config * docs: update tagline * docs: update footer * docs: update document * docs: update document * docs: update document * docs: update document * docs: update document * docs: update document * docs: update document * docs: update document * chore: update readme * docs: update vitepress config * docs: update document * docs: update document * docs: update document * docs: update document * docs: add document that advanced * chore: update document for wording (#5) * chron: update docs/index.md for wording * chron: update docs/index.md for wording - 2 * chron: update docs/index.md, docs/api/use-form.md for wording * chore: update readme * chore: update deps * docs: update document * docs: update vitepress config * chore: update readme * chore: update readme * docs: update examples section with stackblitz * docs: update logo * docs: update document theme * docs: update dcoument * docs: update dcoument * docs: update dcoument Co-authored-by: sp0033212000 <[email protected]>
1 parent 9fc4d67 commit 8a37759

File tree

20 files changed

+1872
-373
lines changed

20 files changed

+1872
-373
lines changed

README.md

Lines changed: 62 additions & 373 deletions
Large diffs are not rendered by default.

docs/.vitepress/config.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { defineConfig } from 'vitepress'
2+
3+
const guide = [
4+
{
5+
text: 'Get Started',
6+
link: '/guide/',
7+
},
8+
]
9+
10+
const api = [
11+
{
12+
text: 'useForm',
13+
link: '/api/use-form',
14+
},
15+
{
16+
text: 'useField',
17+
link: '/api/use-field',
18+
},
19+
{
20+
text: 'useFieldArray',
21+
link: '/api/use-field-array',
22+
},
23+
{
24+
text: 'useFormContext',
25+
link: '/api/use-form-context',
26+
},
27+
]
28+
29+
const advanced = [
30+
{
31+
text: 'Smart Form Component',
32+
link: '/advanced/smart-form-component',
33+
},
34+
]
35+
36+
export default defineConfig({
37+
title: 'Vorms',
38+
titleTemplate: 'Vorms - Vue Form Validate with Composition API',
39+
description: 'Vue Form Validate with Composition API',
40+
41+
42+
head: [
43+
['link', { rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' }],
44+
['meta', { name: 'author', content: 'Alex Liu' }],
45+
['meta', { property: 'og:title', content: 'Vorms' }],
46+
['meta', { property: 'og:description', content: 'Vue Form Validate with Composition API' }],
47+
['meta', { property: 'og:image', content: 'https://vorms.mini-ghost.dev/og.png' }],
48+
['meta', { property: 'og:image:alt', content: 'Vorms' }],
49+
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
50+
['meta', { name: 'twitter:creator', content: '@Minighost_Alex' }],
51+
['meta', { name: 'twitter:image', content: 'https://vorms.mini-ghost.dev/og.png' }],
52+
],
53+
54+
markdown: {
55+
theme: {
56+
light: 'vitesse-light',
57+
dark: 'vitesse-dark',
58+
},
59+
config(md) {
60+
// https://github.com/markdown-it/markdown-it/issues/878
61+
md.linkify.set({
62+
fuzzyLink: false
63+
})
64+
}
65+
},
66+
67+
themeConfig: {
68+
logo: '/favicon.svg',
69+
70+
editLink: {
71+
pattern: 'https://github.com/Mini-ghost/vorms/tree/docs/docs/:path'
72+
},
73+
74+
nav: [
75+
{ text: 'Get Started', link: '/guide/', activeMatch: '/guide/' },
76+
{ text: 'API', link: '/api/use-form', activeMatch: '/api/' },
77+
{ text: 'Examples', link: '/examples/', activeMatch: '/examples/' }
78+
],
79+
80+
socialLinks: [
81+
{ icon: 'github', link: 'https://github.com/Mini-ghost/vorms' },
82+
],
83+
84+
sidebar: [
85+
{
86+
text: 'Guide',
87+
items: guide
88+
},
89+
{
90+
text: 'API Reference',
91+
items: api
92+
},
93+
{
94+
text: 'Advanced',
95+
items: advanced
96+
}
97+
],
98+
99+
footer: {
100+
message: 'Released under the MIT License.',
101+
copyright: 'Copyright © 2022-present Alex Liu'
102+
},
103+
}
104+
})
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script setup lang="ts">
2+
import { onMounted, ref } from 'vue';
3+
import stackblitz from '@stackblitz/sdk'
4+
5+
interface StackblitzEmbedProps {
6+
projectId: string
7+
}
8+
9+
const props = defineProps<StackblitzEmbedProps>()
10+
11+
const rootRef = ref<HTMLElement>()
12+
13+
onMounted(() => {
14+
if(!rootRef.value) return
15+
stackblitz.embedProjectId(rootRef.value, props.projectId, {
16+
openFile: 'src/App.vue',
17+
view: 'preview',
18+
clickToLoad: true,
19+
height: 520,
20+
})
21+
})
22+
</script>
23+
24+
<template>
25+
<div ref="rootRef" />
26+
</template>

docs/.vitepress/theme/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import DefaultTheme from 'vitepress/theme'
2+
3+
// @ts-expect-error
4+
import StackblitzEmbed from './components/StackblitzEmbed.vue'
5+
6+
import './styles/vars.css'
7+
import './styles/main.css'
8+
9+
export default {
10+
...DefaultTheme,
11+
enhanceApp(ctx: any) {
12+
ctx.app.component('StackblitzEmbed', StackblitzEmbed)
13+
}
14+
}
15+

docs/.vitepress/theme/styles/main.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
iframe {
2+
border-width: 0;
3+
}
4+
5+
.VPFeatures .VPFeature {
6+
transition: border-color 0.25s, filter 0.25s;
7+
}
8+
9+
.VPFeatures:has(.VPFeature:hover) .VPFeature:not(:hover) {
10+
opacity: 0.75;
11+
filter: blur(2px);
12+
}
13+
14+
.VPFeature:hover {
15+
border-color: var(--vp-button-brand-border);
16+
}

docs/.vitepress/theme/styles/vars.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Home
3+
*/
4+
:root {
5+
--vp-home-hero-name-color: transparent;
6+
--vp-home-hero-name-background: -webkit-linear-gradient(
7+
120deg,
8+
#0F5096 10%,
9+
#50E669
10+
);
11+
}
12+
13+
:root {
14+
--vp-button-brand-border: #50E669;
15+
--vp-button-brand-bg: #34A77B;
16+
}
17+
18+
/**
19+
* Code
20+
*/
21+
:root {
22+
--vp-code-block-bg: rgba(125,125,125,0.04)
23+
}
24+
25+
:root.dark {
26+
--vp-code-block-bg: rgba(0,0,0,0.2)
27+
}

docs/advanced/smart-form-component.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Smart Form Component
2+
3+
While Vue's `v-model` directive has helped us simplify form input binding, it's still a bit of a pain to deal with large and complex forms.
4+
5+
Smart form components can help us simplify form building even further. We only need to combine those form components, it will automatically match the corresponding form data and complete the input binding.
6+
7+
```vue
8+
<script setup lang="ts">
9+
import SmartForm from './components/SmartForm.vue'
10+
import SmartTextField from './components/SmartTextField.vue'
11+
import SmartSelect from './components/SmartSelect.vue'
12+
13+
interface Values {
14+
drink: string,
15+
sugar: 'no' | 'light' | 'half' | 'half' | 'standard'
16+
}
17+
18+
const initialValues = {
19+
drink: '',
20+
sugar: 'light',
21+
}
22+
23+
const onSubmit = (values: Values) => {
24+
console.log(values);
25+
26+
}
27+
28+
</script>
29+
30+
<template>
31+
<div>
32+
<SmartForm :initial-values="initialValues" @submit="onSubmit">
33+
<SmartTextField name="name" />
34+
<SmartSelect name="sugar" :options="['no', 'light', 'half', 'half', 'standard']" />
35+
36+
<button type="submit">Submit</button>
37+
</SmartForm>
38+
</div>
39+
</template>
40+
```
41+
42+
Let's see how to write those components.
43+
44+
## SmartForm
45+
46+
The SmartForm component will provide vorms's states and methods to a component's descendants.
47+
48+
```vue
49+
<script setup lang="ts">
50+
import { useForm } from '@vorms/core';
51+
52+
type Values = Record<string, any>;
53+
54+
interface SmartFormProps {
55+
initialValues: Values;
56+
}
57+
58+
interface SmartFormEvent {
59+
(event: 'submit', values: Values): void;
60+
}
61+
62+
const props = defineProps<SmartFormProps>();
63+
const emit = defineEmits<SmartFormEvent>();
64+
65+
const { handleSubmit, handleReset } = useForm({
66+
initialValues: props.initialValues,
67+
onSubmit(values) {
68+
emit('submit', values);
69+
},
70+
});
71+
</script>
72+
73+
<template>
74+
<form @submit="handleSubmit" @reset="handleReset">
75+
<slot name="default" />
76+
</form>
77+
</template>
78+
```
79+
80+
## SmartTextField and SmartSelect
81+
82+
Those input components will inject the state and methods provided by the SmartForm component and handle form input binding under the hood.
83+
84+
**SmartTextField**
85+
86+
```vue
87+
<script setup lang="ts">
88+
import { toRef } from 'vue'
89+
import { useField } from '@vorms/core'
90+
91+
interface SmartTextFieldProps {
92+
name: string;
93+
}
94+
95+
const props = defineProps<SmartTextFieldProps>()
96+
97+
const nameRef = toRef(props, 'name')
98+
const { value, attrs } = useField(nameRef)
99+
</script>
100+
101+
<template>
102+
<input v-model="value" type="text" v-bind="attrs">
103+
</template>
104+
```
105+
106+
**SmartSelect**
107+
108+
```vue
109+
<script setup lang="ts">
110+
import { toRef } from 'vue'
111+
import { useField } from '@vorms/core'
112+
113+
interface SmartSelectProps {
114+
name: string;
115+
options: string[]
116+
}
117+
118+
const props = defineProps<SmartSelectProps>()
119+
120+
const nameRef = toRef(props, 'name')
121+
const { value, attrs } = useField(nameRef)
122+
</script>
123+
124+
<template>
125+
<select v-model="value" v-bind="attrs">
126+
<option v-for="item in options" :key="item" :value="item">
127+
{{ item }}
128+
</option>
129+
</select>
130+
</template>
131+
```
132+
133+
Now, you can create and compose complex from in your project without the tears. This ideal is inspired by [React Hook Form](https://react-hook-form.com/advanced-usage#SmartFormComponent)

0 commit comments

Comments
 (0)