pimelon-ui 0.0.84 → 0.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +37 -16
- package/src/components/Autocomplete.vue +5 -5
- package/src/components/Badge.vue +8 -21
- package/src/components/Button.vue +4 -2
- package/src/components/DatePicker.vue +5 -0
- package/src/components/Dialog.vue +6 -7
- package/src/components/Dropdown.vue +77 -50
- package/src/components/FileUploader.vue +3 -3
- package/src/components/Input.vue +3 -2
- package/src/components/LoadingIndicator.vue +20 -5
- package/src/components/Popover.vue +31 -13
- package/src/components/TextEditor/FontColor.vue +108 -0
- package/src/components/TextEditor/Menu.vue +3 -1
- package/src/components/TextEditor/TextEditor.vue +19 -2
- package/src/components/TextEditor/TextEditorFixedMenu.vue +1 -0
- package/src/components/TextEditor/commands.js +8 -0
- package/src/components/TextEditor/index.js +1 -0
- package/src/components/Toast.vue +38 -128
- package/src/components/Tooltip.vue +3 -2
- package/src/components/toast.js +98 -0
- package/src/index.js +18 -5
- package/src/resources/documentResource.js +17 -8
- package/src/resources/index.js +1 -0
- package/src/resources/listResource.js +35 -23
- package/src/resources/local.js +6 -0
- package/src/resources/plugin.js +9 -20
- package/src/resources/resources.js +30 -9
- package/src/style.css +1 -1
- package/src/utils/config.js +9 -0
- package/src/utils/melonRequest.js +105 -0
- package/src/utils/pageMeta.js +3 -1
- package/src/utils/request.js +49 -0
- package/src/components/Modal.vue +0 -67
- package/src/components/Spinner.vue +0 -27
- package/src/components/SuccessMessage.vue +0 -15
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pimelon-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.97",
|
|
4
4
|
"description": "A set of components and utilities for rapid UI development",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "npx prettier --check ./src",
|
|
8
8
|
"prettier": "npx prettier -w ./src",
|
|
9
9
|
"prepare": "husky install",
|
|
10
|
-
"bump-and-release": "git pull --rebase origin main && yarn version --patch && git push && git push --tags"
|
|
10
|
+
"bump-and-release": "git pull --rebase origin main && yarn version --patch && git push && git push --tags",
|
|
11
|
+
"docs:dev": "vitepress dev docs",
|
|
12
|
+
"docs:build": "vitepress build docs",
|
|
13
|
+
"docs:serve": "vitepress serve docs"
|
|
11
14
|
},
|
|
12
15
|
"files": [
|
|
13
16
|
"src"
|
|
@@ -21,34 +24,52 @@
|
|
|
21
24
|
"dependencies": {
|
|
22
25
|
"@headlessui/vue": "^1.5.0",
|
|
23
26
|
"@popperjs/core": "^2.11.2",
|
|
24
|
-
"@tailwindcss/forms": "^0.
|
|
27
|
+
"@tailwindcss/forms": "^0.5.3",
|
|
25
28
|
"@tailwindcss/typography": "^0.5.0",
|
|
26
|
-
"@tiptap/extension-
|
|
27
|
-
"@tiptap/extension-
|
|
28
|
-
"@tiptap/extension-
|
|
29
|
-
"@tiptap/extension-
|
|
30
|
-
"@tiptap/extension-
|
|
31
|
-
"@tiptap/extension-
|
|
32
|
-
"@tiptap/extension-table
|
|
33
|
-
"@tiptap/extension-table-
|
|
34
|
-
"@tiptap/extension-
|
|
35
|
-
"@tiptap/
|
|
36
|
-
"@tiptap/
|
|
37
|
-
"@tiptap/
|
|
29
|
+
"@tiptap/extension-color": "^2.0.0-beta.205",
|
|
30
|
+
"@tiptap/extension-highlight": "^2.0.0-beta.205",
|
|
31
|
+
"@tiptap/extension-image": "^2.0.0-beta.205",
|
|
32
|
+
"@tiptap/extension-link": "^2.0.0-beta.205",
|
|
33
|
+
"@tiptap/extension-mention": "^2.0.0-beta.205",
|
|
34
|
+
"@tiptap/extension-placeholder": "^2.0.0-beta.205",
|
|
35
|
+
"@tiptap/extension-table": "^2.0.0-beta.205",
|
|
36
|
+
"@tiptap/extension-table-cell": "^2.0.0-beta.205",
|
|
37
|
+
"@tiptap/extension-table-header": "^2.0.0-beta.205",
|
|
38
|
+
"@tiptap/extension-table-row": "^2.0.0-beta.205",
|
|
39
|
+
"@tiptap/extension-text-align": "^2.0.0-beta.205",
|
|
40
|
+
"@tiptap/extension-text-style": "^2.0.0-beta.205",
|
|
41
|
+
"@tiptap/extension-typography": "^2.0.0-beta.205",
|
|
42
|
+
"@tiptap/prosemirror-tables": "^1.1.3",
|
|
43
|
+
"@tiptap/starter-kit": "^2.0.0-beta.205",
|
|
44
|
+
"@tiptap/suggestion": "^2.0.0-beta.205",
|
|
45
|
+
"@tiptap/vue-3": "^2.0.0-beta.205",
|
|
38
46
|
"autoprefixer": "^10.4.2",
|
|
39
47
|
"feather-icons": "^4.28.0",
|
|
40
48
|
"idb-keyval": "^6.2.0",
|
|
41
49
|
"postcss": "^8.4.5",
|
|
50
|
+
"prosemirror-commands": "^1.5.0",
|
|
51
|
+
"prosemirror-dropcursor": "1.5.0",
|
|
52
|
+
"prosemirror-gapcursor": "^1.3.1",
|
|
53
|
+
"prosemirror-history": "^1.3.0",
|
|
54
|
+
"prosemirror-keymap": "^1.2.0",
|
|
55
|
+
"prosemirror-model": "^1.18.3",
|
|
56
|
+
"prosemirror-schema-list": "^1.2.2",
|
|
57
|
+
"prosemirror-state": "^1.4.2",
|
|
58
|
+
"prosemirror-transform": "^1.7.0",
|
|
59
|
+
"prosemirror-view": "^1.29.1",
|
|
42
60
|
"showdown": "^2.1.0",
|
|
43
61
|
"socket.io-client": "^4.5.1",
|
|
44
62
|
"tailwindcss": "^3.0.12",
|
|
45
63
|
"tippy.js": "^6.3.7"
|
|
46
64
|
},
|
|
47
65
|
"devDependencies": {
|
|
66
|
+
"cross-fetch": "^3.1.5",
|
|
48
67
|
"husky": "^8.0.3",
|
|
49
68
|
"lint-staged": ">=10",
|
|
50
69
|
"prettier": "2.7.1",
|
|
51
|
-
"prettier-plugin-tailwindcss": "^0.1.13"
|
|
70
|
+
"prettier-plugin-tailwindcss": "^0.1.13",
|
|
71
|
+
"vitepress": "^1.0.0-alpha.29",
|
|
72
|
+
"vue": "^3.2.45"
|
|
52
73
|
},
|
|
53
74
|
"lint-staged": {
|
|
54
75
|
"*.{js,css,md,vue}": "prettier --write"
|
|
@@ -6,11 +6,7 @@
|
|
|
6
6
|
<ComboboxButton
|
|
7
7
|
class="flex w-full items-center justify-between rounded-md bg-gray-100 py-1.5 pl-3 pr-2"
|
|
8
8
|
:class="{ 'rounded-b-none': isComboboxOpen }"
|
|
9
|
-
@click="
|
|
10
|
-
() => {
|
|
11
|
-
openPopover()
|
|
12
|
-
}
|
|
13
|
-
"
|
|
9
|
+
@click="() => openPopover()"
|
|
14
10
|
>
|
|
15
11
|
<span
|
|
16
12
|
class="overflow-hidden text-ellipsis text-base"
|
|
@@ -100,6 +96,8 @@ import {
|
|
|
100
96
|
ComboboxButton,
|
|
101
97
|
} from '@headlessui/vue'
|
|
102
98
|
import Popover from './Popover.vue'
|
|
99
|
+
import Button from './Button.vue'
|
|
100
|
+
import FeatherIcon from './FeatherIcon.vue'
|
|
103
101
|
|
|
104
102
|
export default {
|
|
105
103
|
name: 'Autocomplete',
|
|
@@ -107,6 +105,8 @@ export default {
|
|
|
107
105
|
emits: ['update:modelValue', 'change'],
|
|
108
106
|
components: {
|
|
109
107
|
Popover,
|
|
108
|
+
Button,
|
|
109
|
+
FeatherIcon,
|
|
110
110
|
Combobox,
|
|
111
111
|
ComboboxInput,
|
|
112
112
|
ComboboxOptions,
|
package/src/components/Badge.vue
CHANGED
|
@@ -3,26 +3,14 @@
|
|
|
3
3
|
class="inline-block cursor-default rounded-md px-3 py-1 text-xs font-medium"
|
|
4
4
|
:class="classes"
|
|
5
5
|
>
|
|
6
|
-
<slot>{{
|
|
6
|
+
<slot>{{ label }}</slot>
|
|
7
7
|
</span>
|
|
8
8
|
</template>
|
|
9
9
|
<script>
|
|
10
|
-
|
|
11
|
-
Pending: 'yellow',
|
|
12
|
-
Running: 'yellow',
|
|
13
|
-
Success: 'green',
|
|
14
|
-
Failure: 'red',
|
|
15
|
-
Active: 'green',
|
|
16
|
-
Broken: 'red',
|
|
17
|
-
Updating: 'blue',
|
|
18
|
-
Rejected: 'red',
|
|
19
|
-
Published: 'green',
|
|
20
|
-
Approved: 'green',
|
|
21
|
-
}
|
|
22
|
-
|
|
10
|
+
let validColors = ['gray', 'red', 'yellow', 'green', 'blue']
|
|
23
11
|
export default {
|
|
24
12
|
name: 'Badge',
|
|
25
|
-
props: ['color', '
|
|
13
|
+
props: ['color', 'label', 'colorMap'],
|
|
26
14
|
computed: {
|
|
27
15
|
classes() {
|
|
28
16
|
let color = this.getBadgeColor()
|
|
@@ -41,13 +29,12 @@ export default {
|
|
|
41
29
|
methods: {
|
|
42
30
|
getBadgeColor() {
|
|
43
31
|
let color = this.color
|
|
44
|
-
if (
|
|
45
|
-
|
|
32
|
+
if (this.colorMap) {
|
|
33
|
+
color = this.colorMap[this.label]
|
|
34
|
+
}
|
|
35
|
+
if (!color || !validColors.includes(color)) {
|
|
36
|
+
color = 'gray'
|
|
46
37
|
}
|
|
47
|
-
|
|
48
|
-
let statusColorMap = Object.assign(DEFAULT_COLOR_MAP, this.colorMap || {})
|
|
49
|
-
color = statusColorMap[this.status] || 'gray'
|
|
50
|
-
|
|
51
38
|
return color
|
|
52
39
|
},
|
|
53
40
|
},
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
>
|
|
9
9
|
<LoadingIndicator
|
|
10
10
|
v-if="loading"
|
|
11
|
-
class="
|
|
11
|
+
class="h-3 w-3"
|
|
12
12
|
:class="{
|
|
13
|
+
'mr-2 -ml-1': !icon,
|
|
14
|
+
'm-0.5': icon,
|
|
13
15
|
'text-white': appearance == 'primary',
|
|
14
16
|
'text-gray-600': appearance == 'secondary',
|
|
15
17
|
'text-red-200': appearance == 'danger',
|
|
@@ -24,7 +26,7 @@
|
|
|
24
26
|
aria-hidden="true"
|
|
25
27
|
/>
|
|
26
28
|
<template v-if="loading && loadingText">{{ loadingText }}</template>
|
|
27
|
-
<template v-else-if="icon">
|
|
29
|
+
<template v-else-if="icon && !loading">
|
|
28
30
|
<FeatherIcon :name="icon" class="h-4 w-4" :aria-label="label" />
|
|
29
31
|
</template>
|
|
30
32
|
<span v-else :class="icon ? 'sr-only' : ''">
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<template #target="{ togglePopover }">
|
|
4
4
|
<Input
|
|
5
5
|
type="text"
|
|
6
|
+
icon-left="calendar"
|
|
6
7
|
:class="inputClass"
|
|
7
8
|
:value="
|
|
8
9
|
modelValue && formatValue ? formatValue(modelValue) : modelValue || ''
|
|
@@ -92,6 +93,8 @@
|
|
|
92
93
|
</template>
|
|
93
94
|
|
|
94
95
|
<script>
|
|
96
|
+
import Input from './Input.vue'
|
|
97
|
+
import FeatherIcon from './FeatherIcon.vue'
|
|
95
98
|
import Popover from './Popover.vue'
|
|
96
99
|
|
|
97
100
|
export default {
|
|
@@ -99,6 +102,8 @@ export default {
|
|
|
99
102
|
props: ['modelValue', 'placeholder', 'readonly', 'formatValue', 'inputClass'],
|
|
100
103
|
emits: ['update:modelValue'],
|
|
101
104
|
components: {
|
|
105
|
+
Input,
|
|
106
|
+
FeatherIcon,
|
|
102
107
|
Popover,
|
|
103
108
|
},
|
|
104
109
|
data() {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
@close="open = false"
|
|
11
11
|
>
|
|
12
12
|
<div
|
|
13
|
-
class="flex min-h-screen flex-col items-center px-4
|
|
13
|
+
class="flex min-h-screen flex-col items-center px-4 py-4 text-center"
|
|
14
14
|
:class="dialogPositionClasses"
|
|
15
15
|
>
|
|
16
16
|
<TransitionChild
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
'max-w-3xl': options.size === '3xl',
|
|
47
47
|
'max-w-2xl': options.size === '2xl',
|
|
48
48
|
'max-w-xl': options.size === 'xl',
|
|
49
|
-
'max-w-md': options.size === 'md',
|
|
50
49
|
'max-w-lg': options.size === 'lg' || !options.size,
|
|
50
|
+
'max-w-md': options.size === 'md',
|
|
51
51
|
'max-w-sm': options.size === 'sm',
|
|
52
52
|
'max-w-xs': options.size === 'xs',
|
|
53
53
|
}"
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
v-if="icon"
|
|
61
61
|
class="mx-auto mb-3 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full sm:mx-0 sm:mb-0 sm:mr-4 sm:h-9 sm:w-9"
|
|
62
62
|
:class="{
|
|
63
|
+
'bg-gray-100': !icon.appearance,
|
|
63
64
|
'bg-yellow-100': icon.appearance === 'warning',
|
|
64
65
|
'bg-blue-100': icon.appearance === 'info',
|
|
65
66
|
'bg-red-100': icon.appearance === 'danger',
|
|
@@ -68,8 +69,9 @@
|
|
|
68
69
|
>
|
|
69
70
|
<FeatherIcon
|
|
70
71
|
:name="icon.name"
|
|
71
|
-
class="h-6 w-6
|
|
72
|
+
class="h-6 w-6 sm:h-5 sm:w-5"
|
|
72
73
|
:class="{
|
|
74
|
+
'text-gray-600': !icon.appearance,
|
|
73
75
|
'text-yellow-600': icon.appearance === 'warning',
|
|
74
76
|
'text-blue-600': icon.appearance === 'info',
|
|
75
77
|
'text-red-600': icon.appearance === 'danger',
|
|
@@ -198,10 +200,7 @@ export default {
|
|
|
198
200
|
|
|
199
201
|
let icon = this.options.icon
|
|
200
202
|
if (typeof icon === 'string') {
|
|
201
|
-
icon = {
|
|
202
|
-
name: icon,
|
|
203
|
-
type: 'info',
|
|
204
|
-
}
|
|
203
|
+
icon = { name: icon }
|
|
205
204
|
}
|
|
206
205
|
return icon
|
|
207
206
|
},
|
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Menu as="div" class="relative inline-block text-left" v-slot="{ open }">
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
<Popover :transition="dropdownTransition" :show="open">
|
|
4
|
+
<template #target>
|
|
5
|
+
<MenuButton as="div">
|
|
6
|
+
<slot v-if="$slots.default" v-bind="{ open }" />
|
|
7
|
+
<Button v-else :active="open" v-bind="button">
|
|
8
|
+
{{ button ? button?.label || null : 'Options' }}
|
|
9
|
+
</Button>
|
|
10
|
+
</MenuButton>
|
|
11
|
+
</template>
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
>
|
|
31
|
-
{{ group.group }}
|
|
32
|
-
</div>
|
|
33
|
-
<MenuItem
|
|
34
|
-
v-for="item in group.items"
|
|
35
|
-
:key="item.label"
|
|
36
|
-
v-slot="{ active }"
|
|
37
|
-
>
|
|
38
|
-
<button
|
|
39
|
-
:class="[
|
|
40
|
-
active ? 'bg-gray-100' : 'text-gray-900',
|
|
41
|
-
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
|
|
42
|
-
]"
|
|
43
|
-
@click="item.onClick"
|
|
13
|
+
<template #body>
|
|
14
|
+
<MenuItems
|
|
15
|
+
class="min-w-40 mt-2 divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
|
|
16
|
+
:class="{
|
|
17
|
+
'left-0 origin-top-left': placement == 'left',
|
|
18
|
+
'right-0 origin-top-right': placement == 'right',
|
|
19
|
+
'inset-x-0 origin-top': placement == 'center',
|
|
20
|
+
}"
|
|
21
|
+
>
|
|
22
|
+
<div v-for="group in groups" :key="group.key" class="px-1 py-1">
|
|
23
|
+
<div
|
|
24
|
+
v-if="group.group && !group.hideLabel"
|
|
25
|
+
class="px-2 py-1 text-xs font-semibold uppercase tracking-wider text-gray-500"
|
|
26
|
+
>
|
|
27
|
+
{{ group.group }}
|
|
28
|
+
</div>
|
|
29
|
+
<MenuItem
|
|
30
|
+
v-for="item in group.items"
|
|
31
|
+
:key="item.label"
|
|
32
|
+
v-slot="{ active }"
|
|
44
33
|
>
|
|
45
|
-
<component
|
|
46
|
-
|
|
34
|
+
<component
|
|
35
|
+
v-if="item.component"
|
|
36
|
+
:is="item.component"
|
|
37
|
+
:active="active"
|
|
38
|
+
/>
|
|
39
|
+
<button
|
|
40
|
+
v-else
|
|
41
|
+
:class="[
|
|
42
|
+
active ? 'bg-gray-100' : 'text-gray-900',
|
|
43
|
+
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
|
|
44
|
+
]"
|
|
45
|
+
@click="item.onClick"
|
|
46
|
+
>
|
|
47
47
|
<FeatherIcon
|
|
48
48
|
v-if="item.icon"
|
|
49
49
|
:name="item.icon"
|
|
@@ -53,28 +53,45 @@
|
|
|
53
53
|
<span class="whitespace-nowrap">
|
|
54
54
|
{{ item.label }}
|
|
55
55
|
</span>
|
|
56
|
-
</
|
|
57
|
-
</
|
|
58
|
-
</
|
|
59
|
-
</
|
|
60
|
-
</
|
|
61
|
-
</
|
|
56
|
+
</button>
|
|
57
|
+
</MenuItem>
|
|
58
|
+
</div>
|
|
59
|
+
</MenuItems>
|
|
60
|
+
</template>
|
|
61
|
+
</Popover>
|
|
62
62
|
</Menu>
|
|
63
63
|
</template>
|
|
64
64
|
|
|
65
65
|
<script>
|
|
66
66
|
import { Menu, MenuButton, MenuItems, MenuItem } from '@headlessui/vue'
|
|
67
|
+
import Popover from './Popover.vue'
|
|
68
|
+
import Button from './Button.vue'
|
|
67
69
|
import FeatherIcon from './FeatherIcon.vue'
|
|
68
70
|
|
|
69
71
|
export default {
|
|
70
|
-
name: '
|
|
71
|
-
props:
|
|
72
|
+
name: 'Dropdown',
|
|
73
|
+
props: {
|
|
74
|
+
button: {
|
|
75
|
+
type: Object,
|
|
76
|
+
default: null,
|
|
77
|
+
},
|
|
78
|
+
options: {
|
|
79
|
+
type: Array,
|
|
80
|
+
default: () => [],
|
|
81
|
+
},
|
|
82
|
+
placement: {
|
|
83
|
+
type: String,
|
|
84
|
+
default: 'left',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
72
87
|
components: {
|
|
73
88
|
Menu,
|
|
74
89
|
MenuButton,
|
|
75
90
|
MenuItems,
|
|
76
91
|
MenuItem,
|
|
92
|
+
Button,
|
|
77
93
|
FeatherIcon,
|
|
94
|
+
Popover,
|
|
78
95
|
},
|
|
79
96
|
methods: {
|
|
80
97
|
normalizeDropdownItem(option) {
|
|
@@ -113,6 +130,16 @@ export default {
|
|
|
113
130
|
}
|
|
114
131
|
})
|
|
115
132
|
},
|
|
133
|
+
dropdownTransition() {
|
|
134
|
+
return {
|
|
135
|
+
enterActiveClass: 'transition duration-100 ease-out',
|
|
136
|
+
enterFromClass: 'transform scale-95 opacity-0',
|
|
137
|
+
enterToClass: 'transform scale-100 opacity-100',
|
|
138
|
+
leaveActiveClass: 'transition duration-75 ease-in',
|
|
139
|
+
leaveFromClass: 'transform scale-100 opacity-100',
|
|
140
|
+
leaveToClass: 'transform scale-95 opacity-0',
|
|
141
|
+
}
|
|
142
|
+
},
|
|
116
143
|
},
|
|
117
144
|
}
|
|
118
145
|
</script>
|
|
@@ -130,7 +130,7 @@ class FileUploader {
|
|
|
130
130
|
|
|
131
131
|
export default {
|
|
132
132
|
name: 'FileUploader',
|
|
133
|
-
props: ['fileTypes', 'uploadArgs', '
|
|
133
|
+
props: ['fileTypes', 'uploadArgs', 'validateFile'],
|
|
134
134
|
data() {
|
|
135
135
|
return {
|
|
136
136
|
uploader: null,
|
|
@@ -204,11 +204,11 @@ export default {
|
|
|
204
204
|
.catch((error) => {
|
|
205
205
|
this.uploading = false
|
|
206
206
|
let errorMessage = 'Error Uploading File'
|
|
207
|
-
if (error
|
|
207
|
+
if (error?._server_messages) {
|
|
208
208
|
errorMessage = JSON.parse(
|
|
209
209
|
JSON.parse(error._server_messages)[0]
|
|
210
210
|
).message
|
|
211
|
-
} else if (error
|
|
211
|
+
} else if (error?.exc) {
|
|
212
212
|
errorMessage = JSON.parse(error.exc)[0].split('\n').slice(-2, -1)[0]
|
|
213
213
|
}
|
|
214
214
|
this.error = errorMessage
|
package/src/components/Input.vue
CHANGED
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
ref="input"
|
|
50
50
|
:value="passedInputValue"
|
|
51
51
|
:disabled="disabled"
|
|
52
|
-
:rows="rows
|
|
52
|
+
:rows="rows"
|
|
53
53
|
></textarea>
|
|
54
54
|
<select
|
|
55
55
|
v-if="type === 'select'"
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
</template>
|
|
81
81
|
|
|
82
82
|
<script>
|
|
83
|
-
import { debounce } from '
|
|
83
|
+
import { debounce } from '../index'
|
|
84
84
|
import FeatherIcon from './FeatherIcon.vue'
|
|
85
85
|
|
|
86
86
|
export default {
|
|
@@ -129,6 +129,7 @@ export default {
|
|
|
129
129
|
},
|
|
130
130
|
rows: {
|
|
131
131
|
type: Number,
|
|
132
|
+
default: 3,
|
|
132
133
|
},
|
|
133
134
|
placeholder: {
|
|
134
135
|
type: String,
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<svg
|
|
3
|
+
class="max-w-xs animate-spin"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
fill="none"
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
>
|
|
8
|
+
<circle
|
|
9
|
+
class="opacity-25"
|
|
10
|
+
cx="12"
|
|
11
|
+
cy="12"
|
|
12
|
+
r="10"
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
stroke-width="4"
|
|
15
|
+
></circle>
|
|
16
|
+
<path
|
|
17
|
+
class="opacity-75"
|
|
18
|
+
fill="currentColor"
|
|
19
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
20
|
+
></path>
|
|
21
|
+
</svg>
|
|
3
22
|
</template>
|
|
4
23
|
<script>
|
|
5
|
-
import Spinner from './Spinner.vue'
|
|
6
24
|
export default {
|
|
7
25
|
name: 'LoadingIndicator',
|
|
8
|
-
components: {
|
|
9
|
-
Spinner,
|
|
10
|
-
},
|
|
11
26
|
}
|
|
12
27
|
</script>
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
:class="popoverClass"
|
|
21
21
|
class="popover-container relative z-[100]"
|
|
22
22
|
:style="{ minWidth: targetWidth ? targetWidth + 'px' : null }"
|
|
23
|
-
|
|
23
|
+
@mouseover="pointerOverTargetOrPopup = true"
|
|
24
|
+
@mouseleave="onMouseleave"
|
|
24
25
|
>
|
|
25
26
|
<transition v-bind="popupTransition">
|
|
26
27
|
<div v-show="isOpen">
|
|
@@ -66,7 +67,10 @@ export default {
|
|
|
66
67
|
type: Number,
|
|
67
68
|
default: 0,
|
|
68
69
|
},
|
|
69
|
-
|
|
70
|
+
leaveDelay: {
|
|
71
|
+
type: Number,
|
|
72
|
+
default: 0,
|
|
73
|
+
},
|
|
70
74
|
placement: {
|
|
71
75
|
type: String,
|
|
72
76
|
default: 'bottom-start',
|
|
@@ -85,6 +89,7 @@ export default {
|
|
|
85
89
|
return {
|
|
86
90
|
showPopup: false,
|
|
87
91
|
targetWidth: null,
|
|
92
|
+
pointerOverTargetOrPopup: false,
|
|
88
93
|
}
|
|
89
94
|
},
|
|
90
95
|
watch: {
|
|
@@ -97,6 +102,7 @@ export default {
|
|
|
97
102
|
},
|
|
98
103
|
},
|
|
99
104
|
created() {
|
|
105
|
+
if (typeof window === 'undefined') return
|
|
100
106
|
if (!document.getElementById('melonui-popper-root')) {
|
|
101
107
|
const root = document.createElement('div')
|
|
102
108
|
root.id = 'melonui-popper-root'
|
|
@@ -195,24 +201,22 @@ export default {
|
|
|
195
201
|
}
|
|
196
202
|
},
|
|
197
203
|
open() {
|
|
198
|
-
if (this.isOpen) {
|
|
199
|
-
return
|
|
200
|
-
}
|
|
201
204
|
this.isOpen = true
|
|
202
205
|
this.$nextTick(() => this.setupPopper())
|
|
203
206
|
},
|
|
204
207
|
close() {
|
|
205
|
-
if (!this.isOpen) {
|
|
206
|
-
return
|
|
207
|
-
}
|
|
208
208
|
this.isOpen = false
|
|
209
209
|
},
|
|
210
210
|
onMouseover() {
|
|
211
|
-
this.
|
|
211
|
+
this.pointerOverTargetOrPopup = true
|
|
212
|
+
if (this.leaveTimer) {
|
|
213
|
+
clearTimeout(this.leaveTimer)
|
|
214
|
+
this.leaveTimer = null
|
|
215
|
+
}
|
|
212
216
|
if (this.trigger === 'hover') {
|
|
213
217
|
if (this.hoverDelay) {
|
|
214
218
|
this.hoverTimer = setTimeout(() => {
|
|
215
|
-
if (this.
|
|
219
|
+
if (this.pointerOverTargetOrPopup) {
|
|
216
220
|
this.open()
|
|
217
221
|
}
|
|
218
222
|
}, Number(this.hoverDelay) * 1000)
|
|
@@ -221,13 +225,27 @@ export default {
|
|
|
221
225
|
}
|
|
222
226
|
}
|
|
223
227
|
},
|
|
224
|
-
onMouseleave() {
|
|
225
|
-
this.
|
|
228
|
+
onMouseleave(e) {
|
|
229
|
+
this.pointerOverTargetOrPopup = false
|
|
226
230
|
if (this.hoverTimer) {
|
|
227
231
|
clearTimeout(this.hoverTimer)
|
|
232
|
+
this.hoverTimer = null
|
|
228
233
|
}
|
|
229
234
|
if (this.trigger === 'hover') {
|
|
230
|
-
this.
|
|
235
|
+
if (this.leaveTimer) {
|
|
236
|
+
clearTimeout(this.leaveTimer)
|
|
237
|
+
}
|
|
238
|
+
if (this.leaveDelay) {
|
|
239
|
+
this.leaveTimer = setTimeout(() => {
|
|
240
|
+
if (!this.pointerOverTargetOrPopup) {
|
|
241
|
+
this.close()
|
|
242
|
+
}
|
|
243
|
+
}, Number(this.leaveDelay) * 1000)
|
|
244
|
+
} else {
|
|
245
|
+
if (!this.pointerOverTargetOrPopup) {
|
|
246
|
+
this.close()
|
|
247
|
+
}
|
|
248
|
+
}
|
|
231
249
|
}
|
|
232
250
|
},
|
|
233
251
|
},
|