Skip to content

Commit da9c0a0

Browse files
committed
chore: add dev scripts and local demo app
1 parent 34709a8 commit da9c0a0

File tree

6 files changed

+289
-3
lines changed

6 files changed

+289
-3
lines changed

index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vue Form Builder Demo</title>
8+
</head>
9+
<body>
10+
<div id="app"></div>
11+
<script type="module" src="/src/dev.ts"></script>
12+
</body>
13+
</html>

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
"author": "uwla",
77
"private": false,
88
"scripts": {
9-
"build-types": "vue-tsc && mv dist/main.d.ts vue-form-builder.d.ts",
10-
"build-js": "vite build && mv vue-form-builder.d.ts dist/",
11-
"build": "npm run build-types && npm run build-js",
9+
"build:ts": "vue-tsc && mv dist/main.d.ts vue-form-builder.d.ts",
10+
"build:js": "vite build && mv vue-form-builder.d.ts dist/",
11+
"build": "npm run build:ts && npm run build:js",
12+
"build:demo": "vite build --config vite.config.dev.ts",
13+
"dev": "vite --config vite.config.dev.ts",
1214
"test": "vitest run"
1315
},
1416
"main": "./dist/vue-form-builder.cjs",
@@ -35,6 +37,7 @@
3537
"@vitejs/plugin-vue": "^4.2.3",
3638
"@vue/test-utils": "^2.4.1",
3739
"jsdom": "^22.1.0",
40+
"primevue": "^3.50.0",
3841
"typescript": "^5.0.2",
3942
"vite": "^4.4.5",
4043
"vitest": "^0.34.6",

src/demo/App.vue

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
<template>
2+
<h1>VUE FORM BUILDER DEMO</h1>
3+
<p>Sample demo to showcase VueFormBuilder's functionalities.</p>
4+
<vfb id="options" :fields="fieldsOptions" v-model="m" />
5+
<TabView id="demo" class="tabview-custom">
6+
<TabPanel header="VueFormBuilder">
7+
<vfb v-bind="commonParams" :fields="fields1" />
8+
</TabPanel>
9+
<TabPanel header="PrimeVue">
10+
<vfb v-bind="commonParams" :fields="fields2" provider="primevue" />
11+
</TabPanel>
12+
<TabPanel header="Vuetify">
13+
Because Vuetify's CSS conflicts with PrimeVue's one, the Vuetify
14+
demo will be available in its own demo in the future.
15+
</TabPanel>
16+
</TabView>
17+
</template>
18+
<script lang="ts">
19+
import { defineComponent } from "vue";
20+
21+
const model = {
22+
name: "john",
23+
email: "john@email.test",
24+
gender: "male",
25+
phone: "+1 999 9999-9999",
26+
fruits: ["banana", "avocado"],
27+
website: "http://example.test/",
28+
country: "Canada",
29+
agree: true,
30+
bio: "Commodo proident incididunt anim reprehenderit amet occaecat in exercitation fugiat minim reprehenderit irure voluptate ad.",
31+
};
32+
33+
const emptyModel = {
34+
name: "",
35+
email: "",
36+
gender: "",
37+
phone: "",
38+
fruits: [],
39+
website: "",
40+
country: "",
41+
agree: false,
42+
bio: "",
43+
}
44+
45+
const messages = {
46+
name: "god job",
47+
email: "awesome",
48+
gender: "god job",
49+
bio: "awesome",
50+
fruits: "god job",
51+
photo: "awesome",
52+
country: "god job",
53+
agree: "awesome",
54+
website: "god job",
55+
amount: "awesome job",
56+
birthday: "god job",
57+
};
58+
59+
const errors = {
60+
name: "Name must be longer.",
61+
email: "Email is required.",
62+
phone: "Phone is invalid.",
63+
website: "Website must be valid URL.",
64+
amount: "too much!",
65+
password: "Password must contain letters and numbers.",
66+
bio: "Bio cannot have more than 100 words.",
67+
gender: "Pick a gender",
68+
photo: [
69+
"Photo size must be below 2MB.",
70+
"Photo contains invalid dimensions.",
71+
"Supported formats are JPG or PNG.",
72+
],
73+
fruits: "Choose at most 3 fruits",
74+
country: "Select a country.",
75+
agree: "We cannot procede without agreement.",
76+
};
77+
78+
const validation = {
79+
name: (val: any) => {
80+
if (val.length < 5) return "name must be longer";
81+
if (val.length > 20) return "name must be smaller";
82+
return true;
83+
},
84+
bio: (val: any) => {
85+
if (!val.includes("hello")) return 'bio must include the world "hello"';
86+
return true;
87+
},
88+
fruits: (val: any) => {
89+
if (val.length < 2) return "must choose at least 2 items!";
90+
return true;
91+
},
92+
agree: (val: any) => val,
93+
};
94+
95+
const fields1 = [
96+
"name:name|text|min=5|max=30",
97+
"name:email|email",
98+
"name:phone|tel|label:Phone number",
99+
"name:website|url|label:Personal website",
100+
"name:password|password|label:Choose your password",
101+
"name:birthday|date",
102+
"name:bio|textarea|label:Personal bio|rows=6",
103+
"name:gender|options:male,female",
104+
"name:photo|label:Profile picture|file",
105+
"name:fruits|stacked|checkboxes|options:apple,banana,orange,avocado",
106+
"name:country|stacked|options:United States,Mexico,Canada,Other",
107+
"name:agree|label:Agree to the terms and conditions|checkbox",
108+
"name:token|hidden|label:none|text",
109+
"component:vfb-buttons|label:none|class=block",
110+
];
111+
112+
const fields2 = [
113+
"name:date|component:Calendar|label:Choose a date:|dateFormat=MM dd, yy",
114+
{
115+
name: 'city',
116+
component: 'Dropdown',
117+
props: { options: ['New York', 'Dubai', 'Chicago', 'Moscou', 'Rio de Janeiro'] }
118+
},
119+
{
120+
name: 'rate',
121+
label: 'Rate me!',
122+
component: 'Rating',
123+
props: { cancel: false, stars: 5 },
124+
},
125+
"name:tags|label:Enter tags:|component:Chips",
126+
"name:color|label:Pick a color:|component:ColorPicker|class=color-picker",
127+
"name:name|text|min=5|max=30",
128+
"name:email|email",
129+
"name:phone|tel|label:Phone number",
130+
"name:password|password|label:Choose your password",
131+
"name:bio|textarea|label:Personal bio|rows=6",
132+
"component:vfb-buttons|label:none|class=block",
133+
];
134+
135+
const fields3 : any = [
136+
];
137+
138+
const emptyErrors = {}
139+
const emptyMsg = {}
140+
141+
export default defineComponent({
142+
computed: {
143+
commonParams() {
144+
return {
145+
errors: (this.m.showErrors) ? errors : emptyErrors,
146+
modelValue: (this.m.useModel) ? model : emptyModel,
147+
messages: (this.m.showMessages) ? messages : emptyMsg,
148+
validateOnInput: this.m.validateOnInput,
149+
validateOnSubmit: this.m.validateOnSubmit,
150+
validation: validation,
151+
}
152+
}
153+
},
154+
data: () => {
155+
return {
156+
fields1,
157+
fields2,
158+
fields3,
159+
fieldsOptions: [
160+
'checkbox|name:validateOnInput',
161+
'checkbox|name:validateOnSubmit',
162+
'checkbox|name:showMessages',
163+
'checkbox|name:showErrors',
164+
'checkbox|name:useModel',
165+
],
166+
m: {
167+
validateOnInput: true,
168+
validateOnSubmit: true,
169+
useModel: false,
170+
showMessages: false,
171+
showErrors: false,
172+
},
173+
}
174+
},
175+
});
176+
</script>
177+
<style>
178+
#options .vfb-group {
179+
margin-bottom: 0;
180+
}
181+
182+
#demo form {
183+
max-width: 500px;
184+
border: 1px solid #bbb;
185+
border-radius: 0.25em;
186+
padding: 1em;
187+
margin: 0 auto;
188+
}
189+
190+
.p-chips,
191+
.p-calendar,
192+
.p-inputtext,
193+
.p-textarea,
194+
.p-dropdown {
195+
width: 100%;
196+
}
197+
198+
.color-picker {
199+
margin-left: 8px;
200+
width: 2em;
201+
height: 2em;
202+
}
203+
</style>

src/dev.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { createApp } from "vue";
2+
3+
// Prime Vue
4+
import "primevue/resources/themes/lara-light-teal/theme.css";
5+
import PrimeVue from "primevue/config";
6+
import Button from "primevue/button";
7+
import Calendar from "primevue/calendar";
8+
import Chips from "primevue/chips";
9+
import ColorPicker from "primevue/colorpicker";
10+
import Dialog from "primevue/dialog";
11+
import Dropdown from "primevue/dropdown";
12+
import InputText from "primevue/inputtext";
13+
import Rating from "primevue/rating";
14+
import TabPanel from "primevue/tabpanel";
15+
import TabView from "primevue/tabview";
16+
import Textarea from "primevue/textarea";
17+
18+
// Import local components.
19+
import { components } from "./main";
20+
import App from "./demo/App.vue";
21+
22+
// Create the application.
23+
const app = createApp(App);
24+
25+
// Register local components.
26+
for (const name in components) {
27+
app.component(name, components[name]);
28+
}
29+
30+
// Register PrimeVue components.
31+
app.use(PrimeVue);
32+
app.component("Button", Button);
33+
app.component("Calendar", Calendar);
34+
app.component("Chips", Chips);
35+
app.component("ColorPicker", ColorPicker);
36+
app.component("Dialog", Dialog);
37+
app.component("Dropdown", Dropdown);
38+
app.component("InputText", InputText);
39+
app.component("Rating", Rating);
40+
app.component("TabPanel", TabPanel);
41+
app.component("TabView", TabView);
42+
app.component("Textarea", Textarea);
43+
44+
// Mount the app.
45+
app.mount("#app");

vite.config.dev.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { defineConfig } from "vite";
2+
import vue from "@vitejs/plugin-vue";
3+
4+
const basePath = process.env.APP_BASE ?? "/";
5+
6+
export default defineConfig({
7+
plugins: [vue()],
8+
base: basePath,
9+
build: {
10+
outDir: "demo",
11+
},
12+
});

0 commit comments

Comments
 (0)