frappe-ui 0.0.88 → 0.0.90
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 +10 -3
- package/readme.md +40 -276
- package/src/components/Autocomplete.vue +5 -5
- package/src/components/Badge.vue +8 -21
- package/src/components/DatePicker.vue +5 -0
- package/src/components/Dialog.vue +5 -6
- package/src/components/Dropdown.vue +16 -1
- package/src/components/FileUploader.vue +3 -3
- package/src/components/Input.vue +2 -1
- package/src/components/LoadingIndicator.vue +20 -5
- package/src/components/Popover.vue +31 -7
- package/src/components/TextEditor/TextEditor.vue +2 -0
- package/src/components/TextEditor/index.js +1 -0
- package/src/components/Toast.vue +38 -128
- package/src/components/Tooltip.vue +2 -1
- package/src/components/toast.js +98 -0
- package/src/index.js +18 -5
- package/src/resources/documentResource.js +6 -6
- package/src/resources/index.js +1 -0
- package/src/resources/listResource.js +13 -9
- package/src/resources/local.js +6 -0
- package/src/resources/plugin.js +9 -20
- package/src/resources/resources.js +22 -7
- package/src/style.css +1 -1
- package/src/utils/config.js +9 -0
- package/src/utils/frappeRequest.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": "frappe-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.90",
|
|
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"
|
|
@@ -35,6 +38,7 @@
|
|
|
35
38
|
"@tiptap/extension-table-row": "^2.0.0-beta.22",
|
|
36
39
|
"@tiptap/extension-text-align": "^2.0.0-beta.31",
|
|
37
40
|
"@tiptap/extension-text-style": "^2.0.0-beta.202",
|
|
41
|
+
"@tiptap/extension-typography": "^2.0.0-beta.202",
|
|
38
42
|
"@tiptap/starter-kit": "^2.0.0-beta.191",
|
|
39
43
|
"@tiptap/suggestion": "^2.0.0-beta.195",
|
|
40
44
|
"@tiptap/vue-3": "^2.0.0-beta.96",
|
|
@@ -48,10 +52,13 @@
|
|
|
48
52
|
"tippy.js": "^6.3.7"
|
|
49
53
|
},
|
|
50
54
|
"devDependencies": {
|
|
55
|
+
"cross-fetch": "^3.1.5",
|
|
51
56
|
"husky": ">=6",
|
|
52
57
|
"lint-staged": ">=10",
|
|
53
58
|
"prettier": "2.7.1",
|
|
54
|
-
"prettier-plugin-tailwindcss": "^0.1.13"
|
|
59
|
+
"prettier-plugin-tailwindcss": "^0.1.13",
|
|
60
|
+
"vitepress": "^1.0.0-alpha.29",
|
|
61
|
+
"vue": "^3.2.45"
|
|
55
62
|
},
|
|
56
63
|
"lint-staged": {
|
|
57
64
|
"*.{js,css,md,vue}": "prettier --write"
|
package/readme.md
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/frappe/frappe-ui">
|
|
3
|
+
<img src="./docs/public/frappe-ui-logo.svg" width="250" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
<h1 style="font-size: 24px" align="center">Rapidly build modern frontends for Frappe apps</h1>
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
<p align="center">
|
|
9
|
+
<img alt="MIT License" src="https://img.shields.io/github/license/frappe/frappe-ui"/>
|
|
10
|
+
<img alt="NPM Downloads" src="https://img.shields.io/npm/dm/frappe-ui.svg?style=flat"/>
|
|
11
|
+
</p>
|
|
4
12
|
|
|
5
|
-
Frappe UI
|
|
6
|
-
|
|
13
|
+
Frappe UI provides a set of components and utilities for rapid UI development.
|
|
14
|
+
Components are built using Vue 3 and Tailwind. Along with components, there are
|
|
15
|
+
directives and utilities that make UI development easier.
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
17
|
+
## Links
|
|
18
|
+
|
|
19
|
+
- [Documentation](https://frappeui.com)
|
|
20
|
+
- [Frappe UI Starter Boilerplate](https://github.com/netchampfaris/frappe-ui-starter)
|
|
21
|
+
- [Community](https://github.com/frappe/frappe-ui/discussions)
|
|
12
22
|
|
|
13
23
|
## Installation
|
|
24
|
+
|
|
14
25
|
```sh
|
|
15
26
|
npm install frappe-ui
|
|
16
27
|
# or
|
|
@@ -20,15 +31,14 @@ yarn add frappe-ui
|
|
|
20
31
|
Now, import the FrappeUI plugin and components in your Vue app's `main.js`:
|
|
21
32
|
|
|
22
33
|
```js
|
|
23
|
-
import { createApp } from
|
|
24
|
-
import { FrappeUI
|
|
25
|
-
import App from
|
|
26
|
-
import
|
|
34
|
+
import { createApp } from 'vue'
|
|
35
|
+
import { FrappeUI } from 'frappe-ui'
|
|
36
|
+
import App from './App.vue'
|
|
37
|
+
import './index.css'
|
|
27
38
|
|
|
28
|
-
let app = createApp(App)
|
|
29
|
-
app.use(FrappeUI)
|
|
30
|
-
app.
|
|
31
|
-
app.mount("#app");
|
|
39
|
+
let app = createApp(App)
|
|
40
|
+
app.use(FrappeUI)
|
|
41
|
+
app.mount('#app')
|
|
32
42
|
```
|
|
33
43
|
|
|
34
44
|
In your `tailwind.config.js` file, include the frappe-ui preset:
|
|
@@ -42,277 +52,31 @@ module.exports = {
|
|
|
42
52
|
}
|
|
43
53
|
```
|
|
44
54
|
|
|
45
|
-
## Components
|
|
46
|
-
|
|
47
|
-
Frappe UI ships with a bunch of components. To use a component, you can import it directly from `frappe-ui`:
|
|
48
55
|
```html
|
|
49
56
|
<template>
|
|
50
|
-
|
|
57
|
+
<button>Click me</button>
|
|
51
58
|
</template>
|
|
52
59
|
<script>
|
|
53
|
-
import { Button } from 'frappe-ui'
|
|
54
|
-
export default {
|
|
60
|
+
import { Button } from 'frappe-ui'
|
|
61
|
+
export default {
|
|
55
62
|
components: {
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
</script>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
You can also register components on the root `app` so that you don't have to import them in every component.
|
|
63
|
-
|
|
64
|
-
`main.js`
|
|
65
|
-
```js
|
|
66
|
-
import { createApp } from "vue";
|
|
67
|
-
import { Button, Input } from "frappe-ui";
|
|
68
|
-
|
|
69
|
-
let app = createApp(App);
|
|
70
|
-
app.component("Button", Button);
|
|
71
|
-
app.component("Input", Input);
|
|
72
|
-
app.mount("#app");
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Alert
|
|
76
|
-
```html
|
|
77
|
-
<Alert title="Info">Your account has been created.</Alert>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Avatar
|
|
81
|
-
```html
|
|
82
|
-
<Avatar label="John Doe" />
|
|
83
|
-
<Avatar label="John Doe" imageURL="https://picsum.photos/200" />
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Badge
|
|
87
|
-
```html
|
|
88
|
-
<Badge>Open</Badge>
|
|
89
|
-
<Badge color="green">Completed</Badge>
|
|
90
|
-
<Badge color="red">Error</Badge>
|
|
91
|
-
<Badge color="yellow">Closed</Badge>
|
|
92
|
-
<Badge color="blue">Running</Badge>
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Button
|
|
96
|
-
```html
|
|
97
|
-
<Button>Default</Button>
|
|
98
|
-
<Button type="primary">Primary</Button>
|
|
99
|
-
<Button type="danger">Danger</Button>
|
|
100
|
-
<Button type="white">White</Button>
|
|
101
|
-
<Button icon="x" />
|
|
102
|
-
<Button icon-left="menu">Menu</Button>
|
|
103
|
-
<Button icon-right="external-link">Link</Button>
|
|
104
|
-
<Button :loading="true">Loading</Button>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Card
|
|
108
|
-
```html
|
|
109
|
-
<Card title="Heading" subtitle="Sub text">
|
|
110
|
-
<div class="text-base">Card content</div>
|
|
111
|
-
</Card>
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Dialog
|
|
115
|
-
The Dialog component uses `teleport` feature and requires `#modals` to exist.
|
|
116
|
-
Make sure you add a `<div id="modals"></div>` before the end of your body tag.
|
|
117
|
-
|
|
118
|
-
```html
|
|
119
|
-
<Button @click="dialogOpen = true">Open Dialog</Button>
|
|
120
|
-
<Dialog title="This is Dialog" v-model="dialogOpen">
|
|
121
|
-
<div class="text-base">Dialog content</div>
|
|
122
|
-
</Dialog>
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Dropdown
|
|
126
|
-
The Dropdown component uses `teleport` feature and requires `#popovers` to exist.
|
|
127
|
-
Make sure you add a `<div id="popovers"></div>` before the end of your body tag.
|
|
128
|
-
|
|
129
|
-
```html
|
|
130
|
-
<Dropdown :items="[{ label: 'Option 1' }, { label: 'Option 2' }]">
|
|
131
|
-
<template v-slot="{ toggleDropdown }">
|
|
132
|
-
<Button @click="toggleDropdown()">Open Dropdown</Button>
|
|
133
|
-
</template>
|
|
134
|
-
</Dropdown>
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### ErrorMessage
|
|
138
|
-
```html
|
|
139
|
-
<ErrorMessage message="There was an error" />
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### FeatherIcon
|
|
143
|
-
Uses [`feather-icons`](https://github.com/feathericons/feather) under the hood.
|
|
144
|
-
|
|
145
|
-
```html
|
|
146
|
-
<FeatherIcon class="w-4 h-4" name="menu" />
|
|
147
|
-
<FeatherIcon class="w-4 h-4" name="circle" />
|
|
148
|
-
<FeatherIcon class="w-4 h-4" name="arrow-left" />
|
|
149
|
-
<FeatherIcon class="w-4 h-4" name="arrow-right" />
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### GreenCheckIcon
|
|
153
|
-
```html
|
|
154
|
-
<GreenCheckIcon class="w-4 h-4" />
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Input
|
|
158
|
-
```html
|
|
159
|
-
<Input label="Text" type="text" value="" placeholder="Text" />
|
|
160
|
-
<Input label="Long Text" type="textarea" value="" placeholder="Textarea" />
|
|
161
|
-
<Input
|
|
162
|
-
label="Select"
|
|
163
|
-
type="select"
|
|
164
|
-
value=""
|
|
165
|
-
:options="['Option 1', 'Option 2']"
|
|
166
|
-
/>
|
|
167
|
-
<Input label="Check" type="checkbox" value="" />
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### ListItem
|
|
171
|
-
```html
|
|
172
|
-
<ListItem title="List Item 1" subtitle="Sub text 1">
|
|
173
|
-
<template #actions>
|
|
174
|
-
<Button icon="more-horizontal" />
|
|
175
|
-
</template>
|
|
176
|
-
</ListItem>
|
|
177
|
-
<ListItem title="List Item 2" subtitle="Sub text 2" />
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### LoadingIndicator
|
|
181
|
-
```html
|
|
182
|
-
<LoadingIndicator />
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### LoadingText
|
|
186
|
-
```html
|
|
187
|
-
<LoadingText />
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Spinner
|
|
191
|
-
```html
|
|
192
|
-
<Spinner class="w-5" />
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### SuccessMessage
|
|
196
|
-
```html
|
|
197
|
-
<SuccessMessage message="Completed successfully" />
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
## Directives
|
|
201
|
-
|
|
202
|
-
### onOutsideClick
|
|
203
|
-
This directive is used when you want to execute a function when the user clicks outside of a target element. For e.g., when user clicks outside a dropdown, the dropdown should close.
|
|
204
|
-
|
|
205
|
-
```html
|
|
206
|
-
<button v-on-outside-click="handleOutsideClick">Click me</button>
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
## Utilities
|
|
210
|
-
|
|
211
|
-
### call
|
|
212
|
-
This function wraps `fetch` API. It is built for making web requests to a Frappe server.
|
|
213
|
-
|
|
214
|
-
```js
|
|
215
|
-
call('frappe.client.get_value', {
|
|
216
|
-
doctype: 'ToDo',
|
|
217
|
-
filters: {name: 'adsfasdf'},
|
|
218
|
-
fieldname: 'description'
|
|
219
|
-
})
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### resources
|
|
223
|
-
This is a helper for managing async data fetching in Vue apps that work with a Frappe backend.
|
|
224
|
-
|
|
225
|
-
```html
|
|
226
|
-
<template>
|
|
227
|
-
<div>
|
|
228
|
-
<LoadingText v-if="$resources.todos.loading" />
|
|
229
|
-
<div
|
|
230
|
-
v-for="todo in $resources.todos.data || []"
|
|
231
|
-
:key="todo.name"
|
|
232
|
-
>
|
|
233
|
-
<div>{{ todo.description }}</div>
|
|
234
|
-
<Badge>{{ todo.status }}</Badge>
|
|
235
|
-
</div>
|
|
236
|
-
<ErrorMessage message="$resources.todos.error" />
|
|
237
|
-
</div>
|
|
238
|
-
</template>
|
|
239
|
-
<script>
|
|
240
|
-
import { Badge, LoadingText, ErrorMessage } from 'frappe-ui';
|
|
241
|
-
|
|
242
|
-
export default {
|
|
243
|
-
name: 'ToDos',
|
|
244
|
-
resources: {
|
|
245
|
-
todos: {
|
|
246
|
-
method: 'frappe.client.get_list',
|
|
247
|
-
params: {
|
|
248
|
-
doctype: 'ToDo',
|
|
249
|
-
fields: ['*']
|
|
250
|
-
}
|
|
251
|
-
}
|
|
63
|
+
Button,
|
|
252
64
|
},
|
|
253
|
-
|
|
254
|
-
Badge,
|
|
255
|
-
LoadingText,
|
|
256
|
-
ErrorMessage
|
|
257
|
-
}
|
|
258
|
-
}
|
|
65
|
+
}
|
|
259
66
|
</script>
|
|
260
67
|
```
|
|
261
68
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
This module pre-configures a socketio instance on the port 9000. If you install the FrappeUI plugin, `this.$socket` will be available in all Vue components.
|
|
265
|
-
|
|
266
|
-
Usage:
|
|
267
|
-
```js
|
|
268
|
-
this.$socket.on('list_update', (data) => {
|
|
269
|
-
// handle list update event
|
|
270
|
-
});
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
### tailwind.config
|
|
274
|
-
This is a [tailwind preset](https://tailwindcss.com/docs/presets) that customizes the standard tailwind config to include Frappe design tokens.
|
|
275
|
-
|
|
276
|
-
Usage:
|
|
277
|
-
```js
|
|
278
|
-
module.exports = {
|
|
279
|
-
presets: [
|
|
280
|
-
require('frappe-ui/src/utils/tailwind.config')
|
|
281
|
-
],
|
|
282
|
-
...
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Vue Plugin
|
|
287
|
-
Vue plugin that installs call, resources and socketio in your Vue app
|
|
69
|
+
## Used By
|
|
288
70
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
import { createApp } from "vue";
|
|
292
|
-
import { FrappeUI } from "frappe-ui";
|
|
293
|
-
import App from "./App.vue";
|
|
71
|
+
Frappe UI is being used in a lot of products by
|
|
72
|
+
[Frappe](https://github.com/frappe).
|
|
294
73
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
You can now use these features in your Vue components.
|
|
301
|
-
```html
|
|
302
|
-
<script>
|
|
303
|
-
export default {
|
|
304
|
-
resources: {
|
|
305
|
-
ping: 'frappe.handler.ping'
|
|
306
|
-
},
|
|
307
|
-
mounted() {
|
|
308
|
-
this.$call('ping');
|
|
309
|
-
this.$socket.on('list_update', (data) => {
|
|
310
|
-
// handle list update event
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
</script>
|
|
315
|
-
```
|
|
74
|
+
- [Frappe Cloud](https://frappecloud.com)
|
|
75
|
+
- [Gameplan](https://github.com/frappe/gameplan)
|
|
76
|
+
- [Frappe Desk](https://frappedesk.com)
|
|
77
|
+
- [Frappe Insights](https://github.com/frappe/insights)
|
|
78
|
+
- [Frappe Drive](https://github.com/frappe/drive)
|
|
316
79
|
|
|
317
80
|
## License
|
|
81
|
+
|
|
318
82
|
MIT
|
|
@@ -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
|
},
|
|
@@ -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() {
|
|
@@ -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
|
},
|
|
@@ -64,16 +64,31 @@
|
|
|
64
64
|
|
|
65
65
|
<script>
|
|
66
66
|
import { Menu, MenuButton, MenuItems, MenuItem } from '@headlessui/vue'
|
|
67
|
+
import Button from './Button.vue'
|
|
67
68
|
import FeatherIcon from './FeatherIcon.vue'
|
|
68
69
|
|
|
69
70
|
export default {
|
|
70
71
|
name: 'NewDropdown',
|
|
71
|
-
props:
|
|
72
|
+
props: {
|
|
73
|
+
button: {
|
|
74
|
+
type: Object,
|
|
75
|
+
default: null,
|
|
76
|
+
},
|
|
77
|
+
options: {
|
|
78
|
+
type: Array,
|
|
79
|
+
default: () => [],
|
|
80
|
+
},
|
|
81
|
+
placement: {
|
|
82
|
+
type: String,
|
|
83
|
+
default: 'left',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
72
86
|
components: {
|
|
73
87
|
Menu,
|
|
74
88
|
MenuButton,
|
|
75
89
|
MenuItems,
|
|
76
90
|
MenuItem,
|
|
91
|
+
Button,
|
|
77
92
|
FeatherIcon,
|
|
78
93
|
},
|
|
79
94
|
methods: {
|
|
@@ -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'"
|
|
@@ -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>
|