big update
This commit is contained in:
parent
f58a5106eb
commit
56c40021ba
14
index.html
Normal file
14
index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Vue + TS</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
40
package.json
40
package.json
@ -1,23 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "axp-ui",
|
"name": "axp-ui",
|
||||||
"descriiption": "My helper ui lib",
|
"descriiption": "My helper ui lib",
|
||||||
"version": "1.6.3",
|
"version": "1.7.0",
|
||||||
"homepage": "https://antoxahub.ru/antoxa/axp-ui",
|
"homepage": "https://antoxahub.ru/antoxa/axp-ui",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://antoxahub.ru/antoxa/axp-ui.git"
|
"url": "https://antoxahub.ru/antoxa/axp-ui.git"
|
||||||
},
|
},
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.mjs",
|
||||||
|
"main": "./dist/index.umd.js",
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./dist/index.js"
|
"import": "./dist/index.mjs",
|
||||||
|
"requier": "./dist/index.umd.js"
|
||||||
},
|
},
|
||||||
"./styles/": [
|
"./tailwind.config": "./tailwind.config.ts",
|
||||||
"./src/css/"
|
"./style.css": "./dist/style.css",
|
||||||
],
|
"./style/*": "./src/style/*",
|
||||||
"./tailwind.config": "./tailwind.config.ts"
|
"./tsconfig.json": "./tsconfig.json"
|
||||||
},
|
},
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"tsconfig.json",
|
"tsconfig.json",
|
||||||
@ -25,23 +27,23 @@
|
|||||||
"src/css"
|
"src/css"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup -c --configPlugin rollup-plugin-typescript2",
|
"build": "vite build",
|
||||||
|
"dev": "vite",
|
||||||
"prepare": "npm run build"
|
"prepare": "npm run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"peerDependencies": {
|
||||||
"axp-ts": "^1.9.6",
|
"axp-ts": "^1.9.10",
|
||||||
"vue": "^3.3.4"
|
"vue": "^3.3.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.4.14",
|
"@vitejs/plugin-vue": "^4.3.4",
|
||||||
"postcss": "^8.4.27",
|
"autoprefixer": "^10.4.15",
|
||||||
|
"postcss": "^8.4.29",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"rollup": "^3.27.0",
|
"sass": "^1.66.1",
|
||||||
"rollup-plugin-sass": "^1.12.20",
|
|
||||||
"rollup-plugin-typescript2": "^0.35.0",
|
|
||||||
"rollup-plugin-vue": "^6.0.0",
|
|
||||||
"sass": "^1.64.2",
|
|
||||||
"tailwindcss": "^3.3.3",
|
"tailwindcss": "^3.3.3",
|
||||||
"tslib": "^2.6.1"
|
"typescript": "^5.2.2",
|
||||||
|
"vite": "^4.4.9",
|
||||||
|
"vite-plugin-dts": "^3.5.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import { defineConfig } from 'rollup'
|
|
||||||
import typescript from 'rollup-plugin-typescript2'
|
|
||||||
import vue from 'rollup-plugin-vue'
|
|
||||||
import sass from 'rollup-plugin-sass'
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
input: 'src/index.ts',
|
|
||||||
output: {
|
|
||||||
format: 'esm',
|
|
||||||
dir: 'dist'
|
|
||||||
},
|
|
||||||
plugins: [typescript(), vue(), sass()],
|
|
||||||
external: ['vue', 'axp-ts'],
|
|
||||||
})
|
|
342
src/App.vue
Normal file
342
src/App.vue
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { cFieldsSchema } from 'axp-ts'
|
||||||
|
import { colors, icons } from '.'
|
||||||
|
import {
|
||||||
|
UiBtn,
|
||||||
|
UiIcon,
|
||||||
|
UiIconVisibility,
|
||||||
|
UiAlert,
|
||||||
|
UiForm,
|
||||||
|
UiFieldText,
|
||||||
|
UiFieldNumber,
|
||||||
|
UiFieldPassword,
|
||||||
|
UiFieldPhone,
|
||||||
|
UiFieldDate,
|
||||||
|
UiFieldTextArea,
|
||||||
|
UiFieldSelect,
|
||||||
|
UiFieldSelectGender,
|
||||||
|
UiFieldCheckbox,
|
||||||
|
UiFieldFile,
|
||||||
|
UiTable,
|
||||||
|
UiCard,
|
||||||
|
UiPickerDays
|
||||||
|
} from './components'
|
||||||
|
|
||||||
|
// Test fields.
|
||||||
|
const fieldTextValue = ref('Text field')
|
||||||
|
const fieldTextError = ref('Error message')
|
||||||
|
const fieldNumberValue = ref(new Date().getDay())
|
||||||
|
|
||||||
|
// Test phone number.
|
||||||
|
const testPhoneNumber = ref(996919353)
|
||||||
|
const testPhoneNumberError = ref('')
|
||||||
|
const testPhoneNumberSchema = cFieldsSchema.shape.phone
|
||||||
|
|
||||||
|
const testHandler = () => {
|
||||||
|
try {
|
||||||
|
testPhoneNumberError.value = ''
|
||||||
|
testPhoneNumberSchema.parse(testPhoneNumber.value)
|
||||||
|
} catch (e: any) {
|
||||||
|
testPhoneNumberError.value = 'Number phone not valid'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test checkbox.
|
||||||
|
const testCheckboxValue = ref(true)
|
||||||
|
const testCheckboxError = ref('Error checkbox')
|
||||||
|
|
||||||
|
// Days.
|
||||||
|
const days = ref([1, 3, 5])
|
||||||
|
|
||||||
|
// File.
|
||||||
|
const testFileValue = ref<FileList | undefined>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="layout">
|
||||||
|
<header class="header">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="page-title">AXP-UI My helper ui lib</h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main class="main">
|
||||||
|
<div class="container">
|
||||||
|
<div class="components">
|
||||||
|
<h2 class="title">Components UI:</h2>
|
||||||
|
|
||||||
|
<div class="item btns">
|
||||||
|
<div class="item-title">Buttons</div>
|
||||||
|
<div class="item-content flex">
|
||||||
|
<ui-btn
|
||||||
|
v-for="item in colors"
|
||||||
|
class="mr-2 mb-2"
|
||||||
|
:color="item"
|
||||||
|
:label="item"
|
||||||
|
/>
|
||||||
|
<ui-btn label="Disabled" class="mr-2 mb-2" disabled />
|
||||||
|
<ui-btn label="Icon" icon="edit" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item fields">
|
||||||
|
<div class="item-title">Input fields</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<ui-field-text
|
||||||
|
label="Text"
|
||||||
|
v-model="fieldTextValue"
|
||||||
|
:description="'Description field: ' + fieldTextValue"
|
||||||
|
/>
|
||||||
|
<ui-field-text label="Placeholder" placeholder="Search..." />
|
||||||
|
<ui-field-text
|
||||||
|
model-value="Disabled text field"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<ui-field-text label="Error" v-model:error="fieldTextError" />
|
||||||
|
|
||||||
|
<ui-field-number
|
||||||
|
label="Номер"
|
||||||
|
v-model="fieldNumberValue"
|
||||||
|
:description="'Value field: ' + fieldNumberValue"
|
||||||
|
v-model:error="fieldTextError"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ui-field-password label="Пароль" v-model:error="fieldTextError" />
|
||||||
|
|
||||||
|
<ui-field-phone
|
||||||
|
label="Телефон"
|
||||||
|
v-model="testPhoneNumber"
|
||||||
|
v-model:error="testPhoneNumberError"
|
||||||
|
:description="'Value phone number ' + testPhoneNumber"
|
||||||
|
/>
|
||||||
|
<ui-btn
|
||||||
|
label="Valid phone"
|
||||||
|
color="primary"
|
||||||
|
@click="testHandler"
|
||||||
|
class="mb-4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ui-field-date
|
||||||
|
label="Дата"
|
||||||
|
:modelValue="new Date()"
|
||||||
|
v-model:error="fieldTextError"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ui-field-text-area
|
||||||
|
label="Текстовая область"
|
||||||
|
v-model="fieldTextValue"
|
||||||
|
:description="'Text area value: ' + fieldTextValue"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item fields">
|
||||||
|
<div class="item-title">Выподающие списки</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<ui-field-select-gender label="Выбор пола" />
|
||||||
|
<ui-field-select
|
||||||
|
label="Заблокирован"
|
||||||
|
:modelValue="1"
|
||||||
|
:options="[
|
||||||
|
{ text: 'Выбор 1', value: 1 },
|
||||||
|
{ text: 'Выбор 2', value: 2 }
|
||||||
|
]"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item checkbox">
|
||||||
|
<div class="item-title">Чекбоксы</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<ui-field-checkbox
|
||||||
|
label="Выбрать 1"
|
||||||
|
v-model="testCheckboxValue"
|
||||||
|
:description="'Value checkbox: ' + testCheckboxValue"
|
||||||
|
/>
|
||||||
|
<ui-field-checkbox
|
||||||
|
label="Выбрать 2"
|
||||||
|
:modelValue="true"
|
||||||
|
v-model:error="testCheckboxError"
|
||||||
|
/>
|
||||||
|
<ui-field-checkbox label="Выбрать 3" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item icons">
|
||||||
|
<div class="item-title">Иконки</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="grid grid-cols-4 lg:grid-cols-8 gap-4">
|
||||||
|
<div
|
||||||
|
class="flex flex-col items-center"
|
||||||
|
v-for="item of Object.keys(icons)"
|
||||||
|
>
|
||||||
|
<ui-icon :name="item" class="mb-2" />
|
||||||
|
<div class="mb-4">{{ item }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item alerts">
|
||||||
|
<div class="item-title">Уведомления</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<ui-alert
|
||||||
|
v-for="item in colors"
|
||||||
|
:color="item"
|
||||||
|
:value="'Текстовое уведомление - ' + item"
|
||||||
|
close
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item tables">
|
||||||
|
<div class="item-title">Таблицы</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<ui-table>
|
||||||
|
<thead>
|
||||||
|
<th class="w-0"></th>
|
||||||
|
<th class="w-0">Видимость</th>
|
||||||
|
<th>Название столбца</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<ui-btn icon="edit" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ui-icon-visibility
|
||||||
|
class="m-auto"
|
||||||
|
:modelValue="false"
|
||||||
|
color
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||||
|
Quis delectus magnam hic! Corporis blanditiis sequi quae
|
||||||
|
autem quaerat soluta cupiditate ipsa ducimus quidem ipsum
|
||||||
|
dicta, reiciendis excepturi vero tempora in.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<ui-btn icon="edit" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ui-icon-visibility
|
||||||
|
class="m-auto"
|
||||||
|
:modelValue="true"
|
||||||
|
color
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||||
|
Recusandae asperiores pariatur quasi ad a sunt minus quia
|
||||||
|
omnis! Doloremque sapiente repellat, ea voluptatibus
|
||||||
|
dolor inventore itaque quidem temporibus a asperiores.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<ui-btn icon="edit" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ui-icon-visibility
|
||||||
|
class="m-auto"
|
||||||
|
:modelValue="false"
|
||||||
|
color
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||||
|
Rem facere ratione commodi odit accusantium iusto, harum
|
||||||
|
asperiores explicabo veniam ipsam placeat recusandae quod
|
||||||
|
quisquam! Pariatur est veniam possimus. Mollitia, culpa.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<ui-btn icon="edit" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ui-icon-visibility
|
||||||
|
class="m-auto"
|
||||||
|
:modelValue="true"
|
||||||
|
color
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
|
||||||
|
Necessitatibus esse autem natus, cum consequuntur
|
||||||
|
aspernatur rerum aliquam voluptatum laboriosam harum
|
||||||
|
fuga, deserunt ad corporis ipsum quod nulla atque.
|
||||||
|
Laborum, beatae.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</ui-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item complex">
|
||||||
|
<div class="item-title">Сложные элементы</div>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<ui-card title="Карточка">
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
||||||
|
Similique incidunt sunt fugiat, ratione eveniet consequatur
|
||||||
|
soluta cum sit voluptatem expedita adipisci qui,
|
||||||
|
dignissimos quae? Sed, atque omnis! Dolor, iure molestias!
|
||||||
|
</p>
|
||||||
|
<ui-picker-days v-model="days" />
|
||||||
|
<code class="block mt-4">Дни недели: {{ days }}</code>
|
||||||
|
<template v-slot:actions>
|
||||||
|
<ui-btn label="Отмена" />
|
||||||
|
<ui-btn label="Кнопка" color="accent" />
|
||||||
|
</template>
|
||||||
|
</ui-card>
|
||||||
|
<ui-card title="Картачка с формой">
|
||||||
|
<ui-form>
|
||||||
|
<ui-field-text label="Текстовое поле" />
|
||||||
|
<ui-field-date label="Дата" />
|
||||||
|
<ui-field-file
|
||||||
|
v-model="testFileValue"
|
||||||
|
:description="'Count files: ' + testFileValue?.length"
|
||||||
|
multiple
|
||||||
|
/>
|
||||||
|
</ui-form>
|
||||||
|
</ui-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="sass">
|
||||||
|
@import './style/tailwind.sass'
|
||||||
|
@import './style/common.sass'
|
||||||
|
@import './style/theme.sass'
|
||||||
|
|
||||||
|
.header
|
||||||
|
@apply py-8 border-b
|
||||||
|
.page-title
|
||||||
|
@apply text-primary
|
||||||
|
|
||||||
|
.main
|
||||||
|
@apply py-4
|
||||||
|
.components
|
||||||
|
.title
|
||||||
|
@apply mb-6
|
||||||
|
.item
|
||||||
|
@apply mb-8
|
||||||
|
&-title
|
||||||
|
@apply text-lg font-bold mb-4
|
||||||
|
@apply text-primary
|
||||||
|
&.fields
|
||||||
|
.ui-field:not(:last-child)
|
||||||
|
@apply mb-4
|
||||||
|
</style>
|
@ -1,14 +1,25 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
import type { TColor } from '../colors'
|
import type { TColor } from '../colors'
|
||||||
|
|
||||||
// Props.
|
export type TUiAlertProps = {
|
||||||
const props = defineProps<{
|
|
||||||
color?: TColor
|
color?: TColor
|
||||||
value?: string
|
value?: string
|
||||||
close?: boolean
|
close?: boolean
|
||||||
}>()
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{ (e: 'close'): void }>()
|
export type TUiAlertEmits = {
|
||||||
|
(e: 'close'): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import UiIcon from './Icon.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiAlertProps>()
|
||||||
|
|
||||||
|
// Emit.
|
||||||
|
const emit = defineEmits<TUiAlertEmits>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,26 +1,52 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
import type { TColor } from '../colors'
|
import type { TColor } from '../colors'
|
||||||
import type { TUiIcon } from '../icons'
|
import type { TUiIcon } from '../icons'
|
||||||
|
|
||||||
import UiIcon from './Icon.vue'
|
export type TUiBtnProps = {
|
||||||
|
|
||||||
// Props.
|
|
||||||
const props = defineProps<{
|
|
||||||
label?: string
|
label?: string
|
||||||
type?: 'button' | 'submit'
|
type?: 'button' | 'submit'
|
||||||
color?: TColor
|
color?: TColor
|
||||||
icon?: TUiIcon
|
icon?: TUiIcon
|
||||||
to?: string
|
to?: string
|
||||||
}>()
|
}
|
||||||
|
|
||||||
|
export type TUiBtnEmits = {
|
||||||
|
(e: 'click', v: PointerEvent): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import UiIcon from './Icon.vue'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiBtnProps>()
|
||||||
|
|
||||||
|
// Emits.
|
||||||
|
const emit = defineEmits<TUiBtnEmits>()
|
||||||
|
|
||||||
|
// Handlers.
|
||||||
|
const clickHandler = (e: PointerEvent) => emit('click', e)
|
||||||
|
|
||||||
|
// Computed.
|
||||||
|
const cssClass = computed(() => {
|
||||||
|
let obj: any = {
|
||||||
|
'ui-btn': true,
|
||||||
|
'ui-btn-icon': props.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.color) obj[props.color] = true
|
||||||
|
return obj
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<component
|
<component
|
||||||
class="ui-btn"
|
|
||||||
:is="props.to ? 'router-link' : 'button'"
|
:is="props.to ? 'router-link' : 'button'"
|
||||||
:to="props.to"
|
:to="props.to"
|
||||||
:class="props.color"
|
|
||||||
:type="props.type"
|
:type="props.type"
|
||||||
|
@click="clickHandler"
|
||||||
|
:class="cssClass"
|
||||||
>
|
>
|
||||||
<ui-icon v-if="props.icon" :name="props.icon" />
|
<ui-icon v-if="props.icon" :name="props.icon" />
|
||||||
<div v-if="props.label" class="label">{{ props.label }}</div>
|
<div v-if="props.label" class="label">{{ props.label }}</div>
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
const props = defineProps<{
|
export type TUiCardProps = {
|
||||||
title?: string
|
title?: string
|
||||||
}>()
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps<TUiCardProps>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,32 +1,43 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export type TUiDialogProps = {
|
||||||
|
title?: string
|
||||||
|
open?: boolean
|
||||||
|
close?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TUiDialogEmits = {
|
||||||
|
(e: 'update:open', v: boolean): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import UiIcon from './Icon.vue'
|
import UiIcon from './Icon.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
// Props.
|
||||||
open: { type: Boolean, default: false },
|
const props = defineProps<TUiDialogProps>()
|
||||||
close: { type: Boolean, default: false },
|
|
||||||
title: { type: String }
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:open'])
|
// Emits.
|
||||||
|
const emit = defineEmits<TUiDialogEmits>()
|
||||||
|
|
||||||
|
// Init data.
|
||||||
const dialogState = ref(props.open)
|
const dialogState = ref(props.open)
|
||||||
|
|
||||||
|
// Methods.
|
||||||
const closeDialog = () => {
|
const closeDialog = () => {
|
||||||
dialogState.value = false
|
dialogState.value = false
|
||||||
emit('update:open', false)
|
emit('update:open', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handlers.
|
||||||
const clickWrapperHandler = (e: MouseEvent) => {
|
const clickWrapperHandler = (e: MouseEvent) => {
|
||||||
if (e.target instanceof Element) {
|
if (e.target instanceof Element) {
|
||||||
if (e.target.classList.contains('ui-dialog')) closeDialog()
|
if (e.target.classList.contains('ui-dialog')) closeDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
// Etc.
|
||||||
() => props.open,
|
watch(() => props.open, val => (dialogState.value = val))
|
||||||
val => (dialogState.value = val)
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -34,7 +45,7 @@ watch(
|
|||||||
<div class="ui-dialog-window">
|
<div class="ui-dialog-window">
|
||||||
<div class="ui-dialog-window-header" v-if="props.title">
|
<div class="ui-dialog-window-header" v-if="props.title">
|
||||||
<h4>{{ title }}</h4>
|
<h4>{{ title }}</h4>
|
||||||
<ui-icon name="close" @click="closeDialog" />
|
<ui-icon name="close" @click="closeDialog" class="ui-icon-close" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="$slots.default" class="ui-dialog-window-content">
|
<div v-if="$slots.default" class="ui-dialog-window-content">
|
||||||
<slot name="default" />
|
<slot name="default" />
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
const props = defineProps<{
|
|
||||||
modelValue?: any
|
|
||||||
label?: string
|
|
||||||
type?: 'text' | 'number' | 'date' | 'password' | 'checkbox'
|
|
||||||
error?: string
|
|
||||||
readonly?: boolean
|
|
||||||
disabled?: boolean
|
|
||||||
placeholder?: string
|
|
||||||
tag?: 'input' | 'textarea' | 'select'
|
|
||||||
checked?: boolean
|
|
||||||
options?: { text: string, value: any }[]
|
|
||||||
multiple?: boolean
|
|
||||||
}>()
|
|
||||||
|
|
||||||
// Emits.
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'input', v: any): void
|
|
||||||
(e: 'update:modelValue', v: any): void
|
|
||||||
(e: 'update:error'): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
// Handlers.
|
|
||||||
const inputHandler = (val: any) => {
|
|
||||||
emit('input', val)
|
|
||||||
emit('update:error')
|
|
||||||
|
|
||||||
if (val?.target?.value) {
|
|
||||||
let value: any = val.target.value
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch (props.type) {
|
|
||||||
case 'number':
|
|
||||||
value = Number(value)
|
|
||||||
break
|
|
||||||
case 'date':
|
|
||||||
value = new Date(value)
|
|
||||||
break
|
|
||||||
case 'text':
|
|
||||||
case 'password':
|
|
||||||
case 'checkbox':
|
|
||||||
value = String(value)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} catch (ex) {}
|
|
||||||
|
|
||||||
emit('update:modelValue', value)
|
|
||||||
} else {
|
|
||||||
emit('update:modelValue', undefined)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
:class="{ 'ui-field': true, error: props.error, disabled: props.disabled }"
|
|
||||||
>
|
|
||||||
<div v-if="props.label" class="label">{{ props.label }}</div>
|
|
||||||
<input
|
|
||||||
v-if="!tag || tag === 'input'"
|
|
||||||
class="input"
|
|
||||||
:type="props.type"
|
|
||||||
:value="props.modelValue"
|
|
||||||
:readonly="props.readonly"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
:checked="checked"
|
|
||||||
:placeholder="props.placeholder"
|
|
||||||
@input="inputHandler"
|
|
||||||
/>
|
|
||||||
<textarea
|
|
||||||
v-if="tag === 'textarea'"
|
|
||||||
class="input"
|
|
||||||
:value="props.modelValue"
|
|
||||||
:readonly="props.readonly"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
:placeholder="props.placeholder"
|
|
||||||
@input="inputHandler"
|
|
||||||
/>
|
|
||||||
<select
|
|
||||||
v-if="tag === 'select'"
|
|
||||||
class="input"
|
|
||||||
:value="props.modelValue"
|
|
||||||
:readonly="props.readonly"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
:placeholder="props.placeholder"
|
|
||||||
:multiple="props.multiple"
|
|
||||||
@input="inputHandler"
|
|
||||||
>
|
|
||||||
<option v-for="item in props.options" :value="item.value">
|
|
||||||
{{ item.text }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<div v-if="props.error" class="message">{{ props.error }}</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -1,31 +1,51 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
export type TUiFieldCheckboxProps = TUiFiledWrapperProps & {
|
||||||
|
modelValue?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TUiFieldCheckboxEmits = {
|
||||||
|
(e: 'input', v: Event): void
|
||||||
|
(e: 'update:model-value', v?: boolean): void
|
||||||
|
(e: 'update:error', v?: string): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UiField from './Field.vue'
|
import UiFieldWrapper from './FieldWrapper.vue'
|
||||||
import { computed } from 'vue'
|
|
||||||
|
|
||||||
// Props.
|
// Props.
|
||||||
const props = defineProps<{
|
const props = defineProps<TUiFieldCheckboxProps>()
|
||||||
modelValue?: boolean
|
|
||||||
disabled?: boolean
|
|
||||||
readonly?: boolean
|
|
||||||
}>()
|
|
||||||
|
|
||||||
// Emits.
|
// Emits.
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: boolean): void }>()
|
const emit = defineEmits<TUiFieldCheckboxEmits>()
|
||||||
|
|
||||||
// Value.
|
|
||||||
const value = computed(() => props.modelValue)
|
|
||||||
|
|
||||||
// Handlers.
|
// Handlers.
|
||||||
const updateHandler = () => emit('update:modelValue', !props.modelValue)
|
const inputHandler = (val: Event) => {
|
||||||
|
emit('input', val)
|
||||||
|
emit('update:error')
|
||||||
|
|
||||||
|
if (val.target instanceof HTMLInputElement) {
|
||||||
|
emit('update:model-value', !props.modelValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field
|
<ui-field-wrapper
|
||||||
type="checkbox"
|
:label="props.label"
|
||||||
class="ui-field-checkbox"
|
:error="props.error"
|
||||||
:checked="value"
|
|
||||||
:disabled="props.disabled"
|
:disabled="props.disabled"
|
||||||
:readonly="props.readonly"
|
:readonly="props.readonly"
|
||||||
@input="updateHandler"
|
:description="props.description"
|
||||||
|
class="ui-field-checkbox"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:checked="props.modelValue"
|
||||||
|
:disabled="props.disabled || props.readonly"
|
||||||
|
@input="inputHandler"
|
||||||
/>
|
/>
|
||||||
|
</ui-field-wrapper>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,32 +1,39 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFieldInputProps, TUiFieldInputEmits } from './FieldInput.vue'
|
||||||
|
|
||||||
|
export type TUiFieldDateProps = TUiFieldInputProps<Date>
|
||||||
|
export type TUiFieldDateEmits = TUiFieldInputEmits
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { cFieldsSchema, getDateCommonFormat } from 'axp-ts'
|
import { cFieldsSchema, getDateCommonFormat } from 'axp-ts'
|
||||||
|
import UiFieldInput from './FieldInput.vue'
|
||||||
|
|
||||||
import UiField from './Field.vue'
|
// Props.
|
||||||
|
const props = defineProps<TUiFieldDateProps>()
|
||||||
|
|
||||||
const props = defineProps<{
|
// Emits.
|
||||||
modelValue?: Date
|
const emit = defineEmits<TUiFieldDateEmits>()
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: Date): void }>()
|
|
||||||
|
|
||||||
|
// Etc.
|
||||||
const valueStr = computed({
|
const valueStr = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
try {
|
try {
|
||||||
const value = cFieldsSchema.shape.date.parse(props.modelValue)
|
const value = cFieldsSchema.shape.date.parse(props.modelValue)
|
||||||
const format = getDateCommonFormat(value)
|
return getDateCommonFormat(value)
|
||||||
return format
|
} catch (e) { }
|
||||||
} catch (e) {}
|
|
||||||
},
|
},
|
||||||
set: (val) => {
|
set: val => {
|
||||||
|
emit('update:error')
|
||||||
try {
|
try {
|
||||||
const value = cFieldsSchema.shape.date.parse(val)
|
const value = cFieldsSchema.shape.date.parse(val)
|
||||||
emit('update:modelValue', value)
|
emit('update:model-value', value)
|
||||||
} catch (e) {}
|
} catch (e) { }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field type="date" class="ui-field-date" v-model="valueStr" />
|
<ui-field-input :="{ ...props, ...$attrs }" v-model="valueStr" type="date" />
|
||||||
</template>
|
</template>
|
||||||
|
57
src/components/FieldFile.vue
Normal file
57
src/components/FieldFile.vue
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
type TModelValue = FileList
|
||||||
|
|
||||||
|
export type TUiFieldFileProps = TUiFiledWrapperProps & {
|
||||||
|
modelValue?: TModelValue
|
||||||
|
multiple?: boolean
|
||||||
|
accept?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TUiFieldFileEmits = {
|
||||||
|
(e: 'input', v?: Event): void
|
||||||
|
(e: 'update:model-value', v?: TModelValue): void
|
||||||
|
(e: 'update:error', v?: string): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import UiFieldWrapper from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiFieldFileProps>()
|
||||||
|
|
||||||
|
// Emits.
|
||||||
|
const emit = defineEmits<TUiFieldFileEmits>()
|
||||||
|
|
||||||
|
// Handlers.
|
||||||
|
const inputHandler = (e: Event) => {
|
||||||
|
emit('input', e)
|
||||||
|
emit('update:error')
|
||||||
|
|
||||||
|
if (e.target instanceof HTMLInputElement && e.target.files) {
|
||||||
|
emit('update:model-value', e.target.files)
|
||||||
|
} else {
|
||||||
|
emit('update:model-value')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ui-field-wrapper
|
||||||
|
:label="props.label"
|
||||||
|
:error="props.error"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
:readonly="props.readonly"
|
||||||
|
:description="props.description"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
:multiple="props.multiple"
|
||||||
|
:disabled="props.disabled || props.readonly"
|
||||||
|
:accept="props.accept"
|
||||||
|
@input="inputHandler"
|
||||||
|
/>
|
||||||
|
</ui-field-wrapper>
|
||||||
|
</template>
|
64
src/components/FieldInput.vue
Normal file
64
src/components/FieldInput.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
export type TUiFieldInputProps<T extends string | number | Date> =
|
||||||
|
TUiFiledWrapperProps & {
|
||||||
|
type?: 'text' | 'number' | 'password' | 'date' | 'checkbox'
|
||||||
|
modelValue?: T
|
||||||
|
placeholder?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TUiFieldInputEmits = {
|
||||||
|
(e: 'input', v: Event): void
|
||||||
|
(e: 'update:model-value', v?: string | number | Date): void
|
||||||
|
(e: 'update:error', v?: string): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import UiFieldWrapper from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiFieldInputProps<any>>()
|
||||||
|
|
||||||
|
// Emits.
|
||||||
|
const emit = defineEmits<TUiFieldInputEmits>()
|
||||||
|
|
||||||
|
// Handlers.
|
||||||
|
const inputHandler = (val: Event) => {
|
||||||
|
emit('input', val)
|
||||||
|
emit('update:error')
|
||||||
|
|
||||||
|
if (val.target instanceof HTMLInputElement) {
|
||||||
|
const { value } = val.target
|
||||||
|
switch (props.type) {
|
||||||
|
case 'number':
|
||||||
|
emit('update:model-value', Number(value))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
emit('update:model-value', String(value))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit('update:model-value', undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ui-field-wrapper
|
||||||
|
:label="props.label"
|
||||||
|
:error="props.error"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
:readonly="props.readonly"
|
||||||
|
:description="props.description"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
:type="props.type"
|
||||||
|
:value="props.modelValue"
|
||||||
|
:placeholder="props.placeholder"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
:readonly="props.readonly"
|
||||||
|
@input="inputHandler"
|
||||||
|
/>
|
||||||
|
</ui-field-wrapper>
|
||||||
|
</template>
|
@ -1,7 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFieldInputProps } from './FieldInput.vue'
|
||||||
|
|
||||||
|
export type TUiFieldNumberProps = TUiFieldInputProps<number>
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UiField from './Field.vue'
|
import UiFieldInput from './FieldInput.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiFieldNumberProps>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field type="number" class="ui-field-number" />
|
<ui-field-input :="{ ...props, ...$attrs }" type="number" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFieldInputProps } from './FieldInput.vue'
|
||||||
|
|
||||||
|
export type TFieldPasswordProps = TUiFieldInputProps<string>
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UiField from './Field.vue'
|
import UiFieldInput from './FieldInput.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TFieldPasswordProps>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field type="password" class="ui-field-password" />
|
<ui-field-input :="{ ...props, ...$attrs }" type="password" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,22 +1,32 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFieldInputProps, TUiFieldInputEmits } from './FieldInput.vue'
|
||||||
|
|
||||||
|
export type TUiFieldPhoneProps = TUiFieldInputProps<number>
|
||||||
|
export type TUiFieldPhoneEmits = TUiFieldInputEmits
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { getPhoneNumberFormat, getPhoneNumberValue } from 'axp-ts'
|
import { getPhoneNumberFormat, getPhoneNumberValue } from 'axp-ts'
|
||||||
|
|
||||||
import UiField from './Field.vue'
|
import UiFieldInput from './FieldInput.vue'
|
||||||
|
|
||||||
// Props.
|
// Props.
|
||||||
const props = defineProps<{ modelValue?: number }>()
|
const props = defineProps<TUiFieldPhoneProps>()
|
||||||
|
|
||||||
// Emits.
|
// Emits.
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: number): void }>()
|
const emit = defineEmits<TUiFieldPhoneEmits>()
|
||||||
|
|
||||||
// Value string.
|
// Value string.
|
||||||
const valueStr = computed({
|
const valueStr = computed({
|
||||||
get: () => getPhoneNumberFormat(props.modelValue),
|
get: () => getPhoneNumberFormat(props.modelValue),
|
||||||
set: val => emit('update:modelValue', getPhoneNumberValue(val))
|
set: val => {
|
||||||
|
emit('update:error')
|
||||||
|
emit('update:model-value', getPhoneNumberValue(val))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field v-model="valueStr" class="ui-field-phone" />
|
<ui-field-input :="{ ...props, ...$attrs }" v-model="valueStr" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,27 +1,59 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
import { computed } from 'vue'
|
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||||
import UiField from './Field.vue'
|
|
||||||
|
|
||||||
const props = defineProps<{
|
export type TUiFieldSelectProps = TUiFiledWrapperProps & {
|
||||||
modelValue?: string | string[] | number | number[],
|
modelValue?: string | string[] | number | number[]
|
||||||
|
options?: { text: string; value: string | number }[]
|
||||||
multiple?: boolean
|
multiple?: boolean
|
||||||
options: { text: string, value: any }[]
|
}
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: any): void }>()
|
export type TUiFieldSelectEmits = {
|
||||||
|
(e: 'input', v: Event): void
|
||||||
|
(e: 'update:model-value', v?: string | string[] | number | number[]): void
|
||||||
|
(e: 'update:error', v?: string): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
const displayValue = computed({
|
<script setup lang="ts">
|
||||||
get: () => props.modelValue,
|
import UiFieldWrapper from './FieldWrapper.vue'
|
||||||
set: (val) => emit('update:modelValue', val)
|
|
||||||
})
|
// Props.
|
||||||
|
const props = defineProps<TUiFieldSelectProps>()
|
||||||
|
|
||||||
|
// Emits.
|
||||||
|
const emit = defineEmits<TUiFieldSelectEmits>()
|
||||||
|
|
||||||
|
// Handlers.
|
||||||
|
const inputHandler = (val: Event) => {
|
||||||
|
emit('input', val)
|
||||||
|
emit('update:error')
|
||||||
|
|
||||||
|
if (val.target instanceof HTMLSelectElement) {
|
||||||
|
emit('update:model-value', val.target.value)
|
||||||
|
} else {
|
||||||
|
emit('update:model-value')
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field
|
<ui-field-wrapper
|
||||||
tag="select"
|
:label="props.label"
|
||||||
|
:error="props.error"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
:readonly="props.readonly"
|
||||||
|
:description="props.description"
|
||||||
class="ui-field-select"
|
class="ui-field-select"
|
||||||
:options="props.options"
|
>
|
||||||
|
<select
|
||||||
|
:value="props.modelValue"
|
||||||
:multiple="props.multiple"
|
:multiple="props.multiple"
|
||||||
v-model="displayValue"
|
:disabled="props.disabled || props.readonly"
|
||||||
/>
|
@input="inputHandler"
|
||||||
|
>
|
||||||
|
<option v-for="item in props.options" :value="item.value">
|
||||||
|
{{ item.text }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</ui-field-wrapper>
|
||||||
</template>
|
</template>
|
||||||
|
@ -15,5 +15,5 @@ const options: { text: string, value: TGender }[] = [
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field-select class="ui-field-select-gender" :options="options" />
|
<ui-field-select :options="options" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFieldInputProps } from './FieldInput.vue'
|
||||||
|
|
||||||
|
export type TUiFieldText = TUiFieldInputProps<string>
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UiField from './Field.vue'
|
import UiFieldInput from './FieldInput.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiFieldText>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field class="ui-field-text" />
|
<ui-field-input :="{ ...props, ...$attrs }" type="text" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,7 +1,50 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
export type TUiFieldTextAreaProps = TUiFiledWrapperProps & {
|
||||||
|
modelValue?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TUiFieldTextAreaEmits = {
|
||||||
|
(e: 'input', v: Event): void
|
||||||
|
(e: 'update:model-value', v?: string | number | Date): void
|
||||||
|
(e: 'update:error', v?: string): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UiField from './Field.vue'
|
import UiFieldWrapper from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiFieldTextAreaProps>()
|
||||||
|
|
||||||
|
// Emits.
|
||||||
|
const emit = defineEmits<TUiFieldTextAreaEmits>()
|
||||||
|
|
||||||
|
// Handlers.
|
||||||
|
const inputHandler = (val: Event) => {
|
||||||
|
emit('input', val)
|
||||||
|
emit('update:error')
|
||||||
|
|
||||||
|
if (val.target instanceof HTMLTextAreaElement) {
|
||||||
|
emit('update:model-value', val.target.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ui-field tag="textarea" class="ui-field-textarea" />
|
<ui-field-wrapper
|
||||||
|
:label="props.label"
|
||||||
|
:error="props.error"
|
||||||
|
:disabled="props.disabled"
|
||||||
|
:readonly="props.readonly"
|
||||||
|
:description="props.description"
|
||||||
|
class="ui-field-textarea"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
:value="props.modelValue"
|
||||||
|
:disabled="props.disabled || props.readonly"
|
||||||
|
@input="inputHandler"
|
||||||
|
/>
|
||||||
|
</ui-field-wrapper>
|
||||||
</template>
|
</template>
|
||||||
|
36
src/components/FieldWrapper.vue
Normal file
36
src/components/FieldWrapper.vue
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export type TUiFiledWrapperProps = {
|
||||||
|
label?: string
|
||||||
|
error?: string
|
||||||
|
disabled?: boolean
|
||||||
|
readonly?: boolean
|
||||||
|
description?: string
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiFiledWrapperProps>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:class="{
|
||||||
|
'ui-field': true,
|
||||||
|
error: props.error,
|
||||||
|
disabled: props.disabled,
|
||||||
|
readonly: props.readonly
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="ui-field-wrap">
|
||||||
|
<div v-if="props.label" class="label">{{ props.label }}</div>
|
||||||
|
<div class="input">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="props.description" class="description">
|
||||||
|
{{ props.description }}
|
||||||
|
</div>
|
||||||
|
<div v-if="props.error" class="message">{{ props.error }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -1,16 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
import type { Ref } from 'vue'
|
import type { TNotificationItem, IFormModel } from 'axp-ts'
|
||||||
import type { TNotificationItem, BaseFormModel } from 'axp-ts'
|
|
||||||
|
|
||||||
import { ref, computed, watch } from 'vue'
|
export type TUiFormProps<T = any> = {
|
||||||
import { colors } from '../colors'
|
modelValue?: IFormModel<T>
|
||||||
|
|
||||||
import UiBtn from './Btn.vue'
|
|
||||||
import UiAlert from './Alert.vue'
|
|
||||||
|
|
||||||
// Props.
|
|
||||||
const props = defineProps<{
|
|
||||||
modelValue?: BaseFormModel<any>
|
|
||||||
title?: string
|
title?: string
|
||||||
noTitle?: boolean
|
noTitle?: boolean
|
||||||
messages?: TNotificationItem[]
|
messages?: TNotificationItem[]
|
||||||
@ -18,16 +10,30 @@ const props = defineProps<{
|
|||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
load?: boolean
|
load?: boolean
|
||||||
showAll?: boolean
|
showAll?: boolean
|
||||||
fn?: (obj?: any) => Promise<any>
|
fn?: (obj?: T) => Promise<T>
|
||||||
}>()
|
}
|
||||||
|
|
||||||
// Emits.
|
export type TUiFormEmits<T = any> = {
|
||||||
const emit = defineEmits<{
|
(e: 'submit', v?: IFormModel<T>): void
|
||||||
(e: 'submit', v?: BaseFormModel<any>): void
|
(e: 'failedValid', v?: IFormModel<T>): void
|
||||||
(e: 'failedValid', v?: BaseFormModel<any>): void
|
|
||||||
(e: 'update:load', v: boolean): void
|
(e: 'update:load', v: boolean): void
|
||||||
(e: 'fnCompleted', v?: any): void
|
(e: 'fnCompleted', v?: any): void
|
||||||
}>()
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, watch } from 'vue'
|
||||||
|
import UiBtn from './Btn.vue'
|
||||||
|
import UiAlert from './Alert.vue'
|
||||||
|
|
||||||
|
import { colors } from '../colors'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiFormProps>()
|
||||||
|
|
||||||
|
// Emits.
|
||||||
|
const emit = defineEmits<TUiFormEmits>()
|
||||||
|
|
||||||
// Controls.
|
// Controls.
|
||||||
const ctrls = computed(() => {
|
const ctrls = computed(() => {
|
||||||
@ -35,7 +41,6 @@ const ctrls = computed(() => {
|
|||||||
if (props.showAll) {
|
if (props.showAll) {
|
||||||
return props.modelValue.ctrls
|
return props.modelValue.ctrls
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
|
||||||
return props.modelValue.ctrls.filter(e => !e.hidden)
|
return props.modelValue.ctrls.filter(e => !e.hidden)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +81,6 @@ const submitHandler = async () => {
|
|||||||
if (err.code && err.text)
|
if (err.code && err.text)
|
||||||
if (
|
if (
|
||||||
props.modelValue &&
|
props.modelValue &&
|
||||||
// @ts-ignore
|
|
||||||
props.modelValue.ctrls.find(e => e.key === err.code)
|
props.modelValue.ctrls.find(e => e.key === err.code)
|
||||||
) {
|
) {
|
||||||
props.modelValue.setValidError(err.code, err.text)
|
props.modelValue.setValidError(err.code, err.text)
|
||||||
@ -118,6 +122,9 @@ const getColorMessage = (item: TNotificationItem) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui-form-body">
|
<div class="ui-form-body">
|
||||||
|
<slot v-if="$slots.pre" name="pre" />
|
||||||
|
<slot v-if="$slots.default" name="default" />
|
||||||
|
<template v-else>
|
||||||
<component
|
<component
|
||||||
v-if="props.modelValue"
|
v-if="props.modelValue"
|
||||||
v-for="ctrl in ctrls"
|
v-for="ctrl in ctrls"
|
||||||
@ -127,9 +134,11 @@ const getColorMessage = (item: TNotificationItem) => {
|
|||||||
v-model:error="props.modelValue._errors[ctrl.key]"
|
v-model:error="props.modelValue._errors[ctrl.key]"
|
||||||
:readonly="ctrl.readonly"
|
:readonly="ctrl.readonly"
|
||||||
:disabled="load || props.load || props.disabled || ctrl.disabled"
|
:disabled="load || props.load || props.disabled || ctrl.disabled"
|
||||||
:class="'ui-field-' + ctrl.key"
|
:description="ctrl.description"
|
||||||
|
:class="'ui-field-key-' + ctrl.key"
|
||||||
/>
|
/>
|
||||||
<slot v-if="$slots.default" name="default" />
|
</template>
|
||||||
|
<slot v-if="$slots.post" name="post" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!props.noActions" class="ui-form-actions">
|
<div v-if="!props.noActions" class="ui-form-actions">
|
||||||
<slot v-if="$slots.actions" name="actions" />
|
<slot v-if="$slots.actions" name="actions" />
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
import type { TUiIcon } from '../icons'
|
import type { TUiIcon } from '../icons'
|
||||||
|
|
||||||
|
export type TUiIconProps = {
|
||||||
|
name: TUiIcon
|
||||||
|
fill?: boolean
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { icons } from '../icons'
|
import { icons } from '../icons'
|
||||||
|
|
||||||
// Props.
|
// Props.
|
||||||
const props = defineProps<{
|
const props = defineProps<TUiIconProps>()
|
||||||
name: TUiIcon
|
|
||||||
fill?: boolean
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const iconName = computed(() => {
|
// Etc.
|
||||||
// @ts-ignore
|
const icon = computed(() => icons[props.name])
|
||||||
return icons[props.name]
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -23,7 +25,7 @@ const iconName = computed(() => {
|
|||||||
:fill="fill ? 'currentColor' : 'none'"
|
:fill="fill ? 'currentColor' : 'none'"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="1.2"
|
stroke-width="1.2"
|
||||||
v-html="iconName"
|
v-html="icon"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export type TUiIconVisibilityProps = {
|
||||||
|
modelValue?: boolean,
|
||||||
|
color?: boolean,
|
||||||
|
cursor?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TUiIconVisibilityEmits = {
|
||||||
|
(e: 'update:modelValue', v: boolean): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UiIcon from './Icon.vue'
|
import UiIcon from './Icon.vue'
|
||||||
|
|
||||||
// Props.
|
// Props.
|
||||||
const props = defineProps<{
|
const props = defineProps<TUiIconVisibilityProps>()
|
||||||
modelValue?: boolean,
|
|
||||||
color?: boolean,
|
|
||||||
cursor?: boolean
|
|
||||||
}>()
|
|
||||||
|
|
||||||
// Emits.
|
// Emits.
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v: boolean): void }>()
|
const emit = defineEmits<TUiIconVisibilityEmits>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,17 +1,25 @@
|
|||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
import UiFieldCheckbox from './FieldCheckbox.vue'
|
export type TUiPickerDaysProps = {
|
||||||
|
|
||||||
// Props.
|
|
||||||
const props = defineProps<{
|
|
||||||
modelValue?: number[]
|
modelValue?: number[]
|
||||||
label?: string
|
label?: string
|
||||||
error?: string
|
error?: string
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}>()
|
}
|
||||||
|
|
||||||
|
export type TUiPickerDaysEmits = {
|
||||||
|
(e: 'update:modelValue', v: number[]): void
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import UiFieldCheckbox from './FieldCheckbox.vue'
|
||||||
|
|
||||||
|
// Props.
|
||||||
|
const props = defineProps<TUiPickerDaysProps>()
|
||||||
|
|
||||||
// Emits.
|
// Emits.
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v: number[]): void }>()
|
const emit = defineEmits<TUiPickerDaysEmits>()
|
||||||
|
|
||||||
// Init data.
|
// Init data.
|
||||||
const days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']
|
const days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export type TTheme = 'light' | 'dark'
|
export type TUiThemeName = 'light' | 'dark'
|
||||||
|
|
||||||
|
export type TUiToggleThemeProps = {
|
||||||
|
modelValue?: TUiThemeName
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TUiToggleThemeEmits = {
|
||||||
|
(e: 'update:modelValue', v: TUiThemeName): void
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import UiIcon from './Icon.vue'
|
import UiIcon from './Icon.vue'
|
||||||
|
|
||||||
// Props.
|
// Props.
|
||||||
const props = defineProps<{
|
const props = defineProps<TUiToggleThemeProps>()
|
||||||
modelValue?: TTheme
|
|
||||||
}>()
|
|
||||||
|
|
||||||
// Emits.
|
// Emits.
|
||||||
const emit = defineEmits<{ (e: 'update:modelValue', v: TTheme): void }>()
|
const emit = defineEmits<TUiToggleThemeEmits>()
|
||||||
|
|
||||||
// Handlers.
|
// Handlers.
|
||||||
const clickHandler = ({}: PointerEvent) =>
|
const clickHandler = ({}: PointerEvent) =>
|
||||||
|
@ -1,20 +1,65 @@
|
|||||||
export { default as UiBtn } from './Btn.vue'
|
|
||||||
export { default as UiAlert } from './Alert.vue'
|
export { default as UiAlert } from './Alert.vue'
|
||||||
export { default as UiField } from './Field.vue'
|
export * from './Alert.vue'
|
||||||
export { default as UiFieldText } from './FieldText.vue'
|
|
||||||
export { default as UiFieldTextArea } from './FieldTextArea.vue'
|
export { default as UiBtn } from './Btn.vue'
|
||||||
export { default as UiFieldPassword } from './FieldPassword.vue'
|
export * from './Btn.vue'
|
||||||
export { default as UiFieldNumber } from './FieldNumber.vue'
|
|
||||||
export { default as UiFieldPhone } from './FieldPhone.vue'
|
|
||||||
export { default as UiFieldDate } from './FieldDate.vue'
|
|
||||||
export { default as UiFieldCheckbox } from './FieldCheckbox.vue'
|
|
||||||
export { default as UiFieldSelect } from './FieldSelect.vue'
|
|
||||||
export { default as UiFieldSelectGender } from './FieldSelectGender.vue'
|
|
||||||
export { default as UiPickerDays } from './PickerDays.vue'
|
|
||||||
export { default as UiIcon } from './Icon.vue'
|
|
||||||
export { default as UiIconVisibility } from './IconVisibility.vue'
|
|
||||||
export { default as UiForm } from './Form.vue'
|
|
||||||
export { default as UiCard } from './Card.vue'
|
export { default as UiCard } from './Card.vue'
|
||||||
export { default as UiTable } from './Table.vue'
|
export * from './Card.vue'
|
||||||
|
|
||||||
export { default as UiDialog } from './Dialog.vue'
|
export { default as UiDialog } from './Dialog.vue'
|
||||||
|
export * from './Dialog.vue'
|
||||||
|
|
||||||
|
export { default as UiIcon } from './Icon.vue'
|
||||||
|
export * from './Icon.vue'
|
||||||
|
|
||||||
|
export { default as UiIconVisibility } from './IconVisibility.vue'
|
||||||
|
export * from './IconVisibility.vue'
|
||||||
|
|
||||||
|
export { default as UiTable } from './Table.vue'
|
||||||
|
export * from './Table.vue'
|
||||||
|
|
||||||
export { default as UiToggleTheme } from './ToggleTheme.vue'
|
export { default as UiToggleTheme } from './ToggleTheme.vue'
|
||||||
|
export * from './ToggleTheme.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldWrapper } from './FieldWrapper.vue'
|
||||||
|
export * from './FieldWrapper.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldInput } from './FieldInput.vue'
|
||||||
|
export * from './FieldInput.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldText } from './FieldText.vue'
|
||||||
|
export * from './FieldText.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldNumber } from './FieldNumber.vue'
|
||||||
|
export * from './FieldNumber.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldPassword } from './FieldPassword.vue'
|
||||||
|
export * from './FieldPassword.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldPhone } from './FieldPhone.vue'
|
||||||
|
export * from './FieldPhone.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldDate } from './FieldDate.vue'
|
||||||
|
export * from './FieldDate.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldTextArea } from './FieldTextArea.vue'
|
||||||
|
export * from './FieldTextArea.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldFile } from './FieldFile.vue'
|
||||||
|
export * from './FieldFile.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldCheckbox } from './FieldCheckbox.vue'
|
||||||
|
export * from './FieldCheckbox.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldSelect } from './FieldSelect.vue'
|
||||||
|
export * from './FieldSelect.vue'
|
||||||
|
|
||||||
|
export { default as UiFieldSelectGender } from './FieldSelectGender.vue'
|
||||||
|
export * from './FieldSelectGender.vue'
|
||||||
|
|
||||||
|
export { default as UiPickerDays } from './PickerDays.vue'
|
||||||
|
export * from './PickerDays.vue'
|
||||||
|
|
||||||
|
export { default as UiForm } from './Form.vue'
|
||||||
|
export * from './Form.vue'
|
||||||
|
@ -83,4 +83,4 @@ export const icons = {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TUiIcon = keyof typeof icons
|
export type TIcon = keyof typeof icons
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
export * from './components'
|
export * from './components'
|
||||||
export * from './icons'
|
export * from './icons'
|
||||||
export * from './colors'
|
export * from './colors'
|
||||||
|
|
||||||
|
import './style/tailwind.sass'
|
||||||
|
import './style/common.sass'
|
||||||
|
import './style/theme.sass'
|
||||||
|
3
src/main.ts
Normal file
3
src/main.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
createApp(App).mount('#app')
|
@ -27,28 +27,31 @@
|
|||||||
|
|
||||||
// Ui.
|
// Ui.
|
||||||
.ui
|
.ui
|
||||||
&-btn,
|
|
||||||
&-field .input
|
|
||||||
@apply outline-none
|
|
||||||
@apply h-[38px] text-base
|
|
||||||
|
|
||||||
&-btn
|
&-btn
|
||||||
@apply px-4 border
|
@apply h-[38px] text-base
|
||||||
@apply flex justify-center items-center
|
@apply flex justify-center items-center
|
||||||
|
@apply px-2 border
|
||||||
> *:not(:last-child)
|
> *:not(:last-child)
|
||||||
@apply mr-1
|
@apply mr-2
|
||||||
> .ui-icon:first-child
|
.label
|
||||||
@apply ml-[-5px]
|
@apply text-base font-normal
|
||||||
|
|
||||||
&-field
|
&-field
|
||||||
|
&-wrap
|
||||||
.label
|
.label
|
||||||
@apply mb-1
|
@apply mb-1
|
||||||
.input
|
.input
|
||||||
@apply block w-full border px-2 py-2
|
@apply h-[38px] text-base
|
||||||
|
@apply block w-full border
|
||||||
|
> *
|
||||||
|
@apply w-full h-full px-2 py-2 outline-none
|
||||||
|
.description,
|
||||||
.message
|
.message
|
||||||
@apply mt-1 text-sm
|
@apply w-full pl-1 mt-1 text-sm
|
||||||
|
|
||||||
&-checkbox
|
&-checkbox
|
||||||
|
@apply mb-4
|
||||||
|
.ui-field-wrap
|
||||||
@apply flex items-center justify-start
|
@apply flex items-center justify-start
|
||||||
.label
|
.label
|
||||||
@apply mb-0
|
@apply mb-0
|
||||||
@ -59,7 +62,10 @@
|
|||||||
|
|
||||||
&-textarea
|
&-textarea
|
||||||
.input
|
.input
|
||||||
@apply min-h-[80px]
|
@apply h-auto
|
||||||
|
> *
|
||||||
|
@apply min-h-[94px]
|
||||||
|
@apply leading-5
|
||||||
|
|
||||||
&-alert
|
&-alert
|
||||||
@apply relative border
|
@apply relative border
|
||||||
@ -134,8 +140,8 @@
|
|||||||
@apply flex items-center justify-between py-2 px-3
|
@apply flex items-center justify-between py-2 px-3
|
||||||
> .title
|
> .title
|
||||||
@apply text-lg font-normal
|
@apply text-lg font-normal
|
||||||
.ui-icon
|
.ui-icon-close
|
||||||
@apply w-[30px] h-[30px] p-0 border-0
|
@apply w-[30px] h-[30px] p-0 border-0 cursor-pointer
|
||||||
&:hover
|
&:hover
|
||||||
@apply text-dark
|
@apply text-dark
|
||||||
&-content
|
&-content
|
3
src/style/tailwind.sass
Normal file
3
src/style/tailwind.sass
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base
|
||||||
|
@tailwind components
|
||||||
|
@tailwind utilities
|
@ -33,16 +33,19 @@
|
|||||||
@apply text-white bg-light border-light
|
@apply text-white bg-light border-light
|
||||||
|
|
||||||
&-field
|
&-field
|
||||||
.input
|
.input > *
|
||||||
@apply bg-white dark:bg-white/10 text-dark dark:text-white
|
@apply bg-white dark:bg-white/10 text-dark dark:text-white
|
||||||
|
.description
|
||||||
|
@apply text-dark/50
|
||||||
&.error
|
&.error
|
||||||
.label,
|
.label,
|
||||||
.input,
|
.input,
|
||||||
.message
|
.message
|
||||||
@apply text-error border-error
|
@apply text-error border-error
|
||||||
&:disabled
|
&.disabled
|
||||||
|
@apply text-dark/60
|
||||||
.input
|
.input
|
||||||
@apply bg-light/10 text-dark/60
|
@apply bg-light/10
|
||||||
&-btn
|
&-btn
|
||||||
@apply outline-none
|
@apply outline-none
|
||||||
&:hover:not(:active)
|
&:hover:not(:active)
|
||||||
@ -51,5 +54,6 @@
|
|||||||
&-btn,
|
&-btn,
|
||||||
&-alert,
|
&-alert,
|
||||||
&-field .input,
|
&-field .input,
|
||||||
|
&-field .input > *,
|
||||||
&-card
|
&-card
|
||||||
@apply rounded
|
@apply rounded
|
@ -1,7 +1,7 @@
|
|||||||
import type { Config } from 'tailwindcss'
|
import type { Config } from 'tailwindcss'
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
content: ['./src/components/**/*.vue'],
|
content: ['./src/App.vue', './src/components/**/*.vue'],
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
@ -12,7 +12,7 @@ const config: Config = {
|
|||||||
dark: '#363636',
|
dark: '#363636',
|
||||||
light: '#f1f1f1',
|
light: '#f1f1f1',
|
||||||
|
|
||||||
info: '#2196f3',
|
info: '#00b8ff',
|
||||||
warning: '#ff9800',
|
warning: '#ff9800',
|
||||||
success: '#2dd633',
|
success: '#2dd633',
|
||||||
error: '#f00000'
|
error: '#f00000'
|
||||||
|
30
vite.config.ts
Normal file
30
vite.config.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import dts from 'vite-plugin-dts'
|
||||||
|
|
||||||
|
import postcss from 'postcss'
|
||||||
|
|
||||||
|
import autoprefixer from 'autoprefixer'
|
||||||
|
import tailwindcss from 'tailwindcss'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue(), dts()],
|
||||||
|
css: {
|
||||||
|
postcss: postcss([autoprefixer(), tailwindcss()])
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: 'src/index.ts',
|
||||||
|
name: 'axp-ui',
|
||||||
|
fileName: 'index'
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: ['vue'],
|
||||||
|
output: {
|
||||||
|
globals: {
|
||||||
|
vue: 'Vue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user