add form properties and tailwind script
This commit is contained in:
64
web/package-lock.json
generated
64
web/package-lock.json
generated
@ -17,7 +17,9 @@
|
|||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.10.2",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"@vue/tsconfig": "^0.7.0",
|
"@vue/tsconfig": "^0.7.0",
|
||||||
|
"autoprefixer": "^10.4.20",
|
||||||
"npm-run-all2": "^7.0.2",
|
"npm-run-all2": "^7.0.2",
|
||||||
|
"postcss": "^8.4.49",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "~5.6.3",
|
"typescript": "~5.6.3",
|
||||||
"vite": "^6.0.5",
|
"vite": "^6.0.5",
|
||||||
@ -1783,6 +1785,44 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/autoprefixer": {
|
||||||
|
"version": "10.4.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
||||||
|
"integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/autoprefixer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"browserslist": "^4.23.3",
|
||||||
|
"caniuse-lite": "^1.0.30001646",
|
||||||
|
"fraction.js": "^4.3.7",
|
||||||
|
"normalize-range": "^0.1.2",
|
||||||
|
"picocolors": "^1.0.1",
|
||||||
|
"postcss-value-parser": "^4.2.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"autoprefixer": "bin/autoprefixer"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || >=14"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"postcss": "^8.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
@ -2359,6 +2399,20 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fraction.js": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://github.com/sponsors/rawify"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs-extra": {
|
"node_modules/fs-extra": {
|
||||||
"version": "11.2.0",
|
"version": "11.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
|
||||||
@ -2993,6 +3047,16 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/normalize-range": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/npm-normalize-package-bin": {
|
"node_modules/npm-normalize-package-bin": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz",
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite --host",
|
||||||
"build": "run-p type-check \"build-only {@}\" --",
|
"build": "run-p type-check \"build-only {@}\" --",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build-only": "vite build",
|
"build-only": "vite build",
|
||||||
"type-check": "vue-tsc --build"
|
"type-check": "vue-tsc --build",
|
||||||
|
"tailwindcss": "npx tailwindcss -i ./src/input.css -o ./src/output.css --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pinia": "^2.3.0",
|
"pinia": "^2.3.0",
|
||||||
@ -20,7 +21,9 @@
|
|||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.10.2",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"@vue/tsconfig": "^0.7.0",
|
"@vue/tsconfig": "^0.7.0",
|
||||||
|
"autoprefixer": "^10.4.20",
|
||||||
"npm-run-all2": "^7.0.2",
|
"npm-run-all2": "^7.0.2",
|
||||||
|
"postcss": "^8.4.49",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "~5.6.3",
|
"typescript": "~5.6.3",
|
||||||
"vite": "^6.0.5",
|
"vite": "^6.0.5",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<form @submit.prevent="handleSubmit" class="space-y-2 p-6 bg-white shadow-lg rounded-lg max-w-md mx-auto">
|
<form @submit.prevent="handleSubmit" class="">
|
||||||
|
<h3 v-if="!!formTitle" class="text-xl font-semibold mb-4">{{formTitle}}</h3>
|
||||||
<div v-for="input in formInputs" :key="input.id" class="flex flex-col">
|
<div v-for="input in formInputs" :key="input.id" class="flex flex-col">
|
||||||
<!-- if showLabel is undefined or set to true then show the label-->
|
<!-- if showLabel is undefined or set to true then show the label-->
|
||||||
<label v-if="input.showLabel === undefined || input.showLabel" :for="input.id" class="mb-2 font-semibold text-gray-700">{{ input.label }}</label>
|
<label v-if="input.showLabel === undefined || input.showLabel" :for="input.id" class="mb-2 font-semibold text-gray-700">{{ input.label }}</label>
|
||||||
@ -95,13 +96,13 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="px-6 py-3 bg-blue-600 text-white font-semibold rounded-md shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
<button type="submit" class="px-6 py-3 bg-blue-600 text-white font-semibold rounded-md shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||||
Submit
|
{{ !!submitLabel ? submitLabel : 'Submit' }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, defineEmits } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
|
|
||||||
export interface FormInput {
|
export interface FormInput {
|
||||||
id: string;
|
id: string;
|
||||||
@ -116,7 +117,7 @@ export interface FormInput {
|
|||||||
options?: { label: string, value: string }[]; // For select, radio, and checkbox types
|
options?: { label: string, value: string }[]; // For select, radio, and checkbox types
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{ formInputs: FormInput[] }>();
|
const props = defineProps<{ formInputs: FormInput[], submitLabel?: string, formTitle?: string }>();
|
||||||
const emit = defineEmits(['send'])
|
const emit = defineEmits(['send'])
|
||||||
|
|
||||||
const formData = reactive<Record<string, any>>({});
|
const formData = reactive<Record<string, any>>({});
|
||||||
|
@ -2,12 +2,33 @@
|
|||||||
<div class="min-h-screen bg-gray-100 flex flex-row items-start p-4">
|
<div class="min-h-screen bg-gray-100 flex flex-row items-start p-4">
|
||||||
<div class="flex-col flex-1 items-center justify-center p-4">
|
<div class="flex-col flex-1 items-center justify-center p-4">
|
||||||
<h2 class="text-xl font-bold mb-4">Form Builder</h2>
|
<h2 class="text-xl font-bold mb-4">Form Builder</h2>
|
||||||
<DynamicForm :formInputs="formBuilderInputs" @send="handleFormBuilderSubmit" />
|
<div>
|
||||||
|
<DynamicForm
|
||||||
|
class="space-y-2 p-6 bg-white shadow-lg rounded-lg max-w-md"
|
||||||
|
:formInputs="formBuilderPropertiesInputs"
|
||||||
|
@send="handleFormPropertiesSubmit"
|
||||||
|
form-title="Form Properties"
|
||||||
|
submit-label="Update Form"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6">
|
||||||
|
<DynamicForm
|
||||||
|
class="space-y-2 p-6 bg-white shadow-lg rounded-lg max-w-md"
|
||||||
|
:formInputs="formBuilderFieldInputs"
|
||||||
|
@send="handleFormBuilderSubmit"
|
||||||
|
form-title="Add a new field"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="generatedFormInputs.length" class="flex-col flex-1 items-center justify-center p-4">
|
<div v-if="generatedFormInputs.length" class="flex-col flex-1 items-center justify-center p-4">
|
||||||
<h2 class="text-xl font-bold mb-4">Generated Form</h2>
|
<h2 class="text-xl font-bold mb-4">Generated Form</h2>
|
||||||
<DynamicForm :formInputs="generatedFormInputs" />
|
<DynamicForm
|
||||||
|
class="space-y-2 p-6 bg-white shadow-lg rounded-lg max-w-md"
|
||||||
|
:formInputs="generatedFormInputs"
|
||||||
|
:submitLabel="submitLabel"
|
||||||
|
:formTitle="formTitle"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -17,7 +38,32 @@ import { ref } from 'vue';
|
|||||||
import DynamicForm from './DynamicForm.vue';
|
import DynamicForm from './DynamicForm.vue';
|
||||||
import type {FormInput} from "@/components/DynamicForm.vue";
|
import type {FormInput} from "@/components/DynamicForm.vue";
|
||||||
|
|
||||||
const formBuilderInputs = ref<FormInput[]>([
|
const formBuilderPropertiesInputs = ref<FormInput[]>([
|
||||||
|
{
|
||||||
|
id: 'formTitle',
|
||||||
|
label: 'Form Title',
|
||||||
|
type: 'text',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'formDescription',
|
||||||
|
label: 'Form Description',
|
||||||
|
type: 'textarea',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'submitLabel',
|
||||||
|
label: 'Submit Button Label',
|
||||||
|
type: 'text',
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const formTitle = ref('');
|
||||||
|
const formDescription = ref('');
|
||||||
|
const submitLabel = ref('');
|
||||||
|
|
||||||
|
const formBuilderFieldInputs = ref<FormInput[]>([
|
||||||
{
|
{
|
||||||
id: 'fieldType',
|
id: 'fieldType',
|
||||||
label: 'Field Type',
|
label: 'Field Type',
|
||||||
@ -107,6 +153,12 @@ const formBuilderInputs = ref<FormInput[]>([
|
|||||||
|
|
||||||
const generatedFormInputs = ref<FormInput[]>([]);
|
const generatedFormInputs = ref<FormInput[]>([]);
|
||||||
|
|
||||||
|
const handleFormPropertiesSubmit = (formData: Record<string, any>) => {
|
||||||
|
formTitle.value = formData.formTitle;
|
||||||
|
formDescription.value = formData.formDescription;
|
||||||
|
submitLabel.value = formData.submitLabel;
|
||||||
|
};
|
||||||
|
|
||||||
const handleFormBuilderSubmit = (formData: Record<string, any>) => {
|
const handleFormBuilderSubmit = (formData: Record<string, any>) => {
|
||||||
const newField: FormInput = {
|
const newField: FormInput = {
|
||||||
id: formData.fieldID,
|
id: formData.fieldID,
|
||||||
@ -124,7 +176,7 @@ const handleFormBuilderSubmit = (formData: Record<string, any>) => {
|
|||||||
generatedFormInputs.value.push(newField);
|
generatedFormInputs.value.push(newField);
|
||||||
|
|
||||||
// Reset form builder fields
|
// Reset form builder fields
|
||||||
formBuilderInputs.value.forEach(input => {
|
formBuilderFieldInputs.value.forEach(input => {
|
||||||
if (input.type === 'checkbox' || input.type === 'multi-input') {
|
if (input.type === 'checkbox' || input.type === 'multi-input') {
|
||||||
formData[input.id] = [];
|
formData[input.id] = [];
|
||||||
if (input.id === 'showLabel') { // showLabel should default to true
|
if (input.id === 'showLabel') { // showLabel should default to true
|
||||||
|
@ -562,33 +562,20 @@ video {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx-auto {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb-2 {
|
.mb-2 {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ml-2 {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb-4 {
|
.mb-4 {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb-6 {
|
.ml-2 {
|
||||||
margin-bottom: 1.5rem;
|
margin-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-12 {
|
.mt-6 {
|
||||||
margin-top: 3rem;
|
margin-top: 1.5rem;
|
||||||
}
|
|
||||||
|
|
||||||
.block {
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex {
|
.flex {
|
||||||
@ -615,10 +602,6 @@ video {
|
|||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-grow {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-row {
|
.flex-row {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
@ -627,10 +610,6 @@ video {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-wrap {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.items-start {
|
.items-start {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
@ -639,20 +618,10 @@ video {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.justify-start {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.justify-center {
|
.justify-center {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
|
||||||
--tw-space-y-reverse: 0;
|
|
||||||
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
|
||||||
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
|
||||||
}
|
|
||||||
|
|
||||||
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-x-reverse: 0;
|
--tw-space-x-reverse: 0;
|
||||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||||
@ -687,36 +656,26 @@ video {
|
|||||||
background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
|
background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-white {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-gray-100 {
|
.bg-gray-100 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-white {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
.p-3 {
|
.p-3 {
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-6 {
|
|
||||||
padding: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-4 {
|
.p-4 {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.px-6 {
|
.p-6 {
|
||||||
padding-left: 1.5rem;
|
padding: 1.5rem;
|
||||||
padding-right: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-3 {
|
|
||||||
padding-top: 0.75rem;
|
|
||||||
padding-bottom: 0.75rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.px-3 {
|
.px-3 {
|
||||||
@ -724,14 +683,19 @@ video {
|
|||||||
padding-right: 0.75rem;
|
padding-right: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.px-6 {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
padding-right: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.py-2 {
|
.py-2 {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-2xl {
|
.py-3 {
|
||||||
font-size: 1.5rem;
|
padding-top: 0.75rem;
|
||||||
line-height: 2rem;
|
padding-bottom: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-xl {
|
.text-xl {
|
||||||
@ -739,22 +703,12 @@ video {
|
|||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-semibold {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-bold {
|
.font-bold {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-gray-700 {
|
.font-semibold {
|
||||||
--tw-text-opacity: 1;
|
font-weight: 600;
|
||||||
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-white {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-blue-600 {
|
.text-blue-600 {
|
||||||
@ -762,11 +716,21 @@ video {
|
|||||||
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
|
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-gray-700 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
.text-red-600 {
|
.text-red-600 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(220 38 38 / var(--tw-text-opacity, 1));
|
color: rgb(220 38 38 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-white {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
.shadow-lg {
|
.shadow-lg {
|
||||||
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||||
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
||||||
|
@ -3,6 +3,8 @@ import { fileURLToPath, URL } from 'node:url'
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
|
import tailwind from "tailwindcss";
|
||||||
|
import autoprefixer from "autoprefixer";
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@ -10,6 +12,11 @@ export default defineConfig({
|
|||||||
vue(),
|
vue(),
|
||||||
vueDevTools(),
|
vueDevTools(),
|
||||||
],
|
],
|
||||||
|
css: {
|
||||||
|
postcss: {
|
||||||
|
plugins: [tailwind, autoprefixer],
|
||||||
|
}
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
|
Reference in New Issue
Block a user