frappe-ui 0.1.13 → 0.1.15

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frappe-ui",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "A set of components and utilities for rapid UI development",
5
5
  "main": "./src/index.js",
6
6
  "scripts": {
@@ -149,7 +149,7 @@
149
149
  </template>
150
150
 
151
151
  <script>
152
- import { computed } from 'vue'
152
+ import { computed, ref } from 'vue'
153
153
  import {
154
154
  Dialog as HDialog,
155
155
  DialogPanel,
@@ -194,34 +194,27 @@ export default {
194
194
  handler(actions) {
195
195
  if (!actions) return
196
196
  this.dialogActions = actions.map((action) => {
197
- let _action = {
197
+ let loading = ref(false)
198
+ return {
198
199
  ...action,
199
- loading: action.loading || false,
200
- _onClick: action.onClick,
201
- onClick: () => this.handleAction(_action),
200
+ loading,
201
+ onClick: !action.onClick
202
+ ? this.close
203
+ : async () => {
204
+ loading.value = true
205
+ try {
206
+ await action.onClick()
207
+ } finally {
208
+ loading.value = false
209
+ }
210
+ },
202
211
  }
203
- return _action
204
212
  })
205
213
  },
206
214
  immediate: true,
207
215
  },
208
216
  },
209
217
  methods: {
210
- handleAction(action) {
211
- if (action._onClick && typeof action._onClick === 'function') {
212
- action.loading = true
213
- let result = action._onClick({ close: this.close })
214
- if (result && result.then) {
215
- result
216
- .then(() => (action.loading = false))
217
- .catch(() => (action.loading = false))
218
- } else {
219
- action.loading = false
220
- }
221
- } else {
222
- this.close()
223
- }
224
- },
225
218
  close() {
226
219
  this.open = false
227
220
  },
@@ -54,6 +54,19 @@ const variants = ['subtle', 'outline']
54
54
  />
55
55
  </div>
56
56
  </Variant>
57
+ <Variant title="select">
58
+ <div class="p-2">
59
+ <FormControl
60
+ type="autocomplete"
61
+ :options="[
62
+ { label: 'One', value: '1' },
63
+ { label: 'Two', value: '2' },
64
+ { label: 'Three', value: '3' },
65
+ ]"
66
+ v-bind="state"
67
+ />
68
+ </div>
69
+ </Variant>
57
70
  <Variant title="checkbox">
58
71
  <div class="p-2">
59
72
  <FormControl type="checkbox" v-bind="state" />
@@ -12,6 +12,17 @@
12
12
  <slot name="prefix" />
13
13
  </template>
14
14
  </Select>
15
+ <Autocomplete
16
+ v-else-if="type === 'autocomplete'"
17
+ v-bind="{ ...controlAttrs }"
18
+ >
19
+ <template #prefix v-if="$slots.prefix">
20
+ <slot name="prefix" />
21
+ </template>
22
+ <template #item-prefix="itemPrefixProps" v-if="$slots['item-prefix']">
23
+ <slot name="item-prefix" v-bind="itemPrefixProps" />
24
+ </template>
25
+ </Autocomplete>
15
26
  <Textarea
16
27
  v-else-if="type === 'textarea'"
17
28
  :id="id"
@@ -43,11 +54,12 @@ import type { TextInputTypes } from './types/TextInput'
43
54
  import Select from './Select.vue'
44
55
  import Textarea from './Textarea.vue'
45
56
  import Checkbox from './Checkbox.vue'
57
+ import Autocomplete from './Autocomplete.vue'
46
58
 
47
59
  interface FormControlProps {
48
60
  label?: string
49
61
  description?: string
50
- type?: TextInputTypes | 'textarea' | 'select' | 'checkbox'
62
+ type?: TextInputTypes | 'textarea' | 'select' | 'checkbox' | 'autocomplete'
51
63
  size?: 'sm' | 'md'
52
64
  }
53
65
 
@@ -0,0 +1,21 @@
1
+ ## Props
2
+
3
+ ### Tabs
4
+
5
+ It is an array of objects which contains the following attributes:
6
+
7
+ 1. `label` is the name of the tab, it is required.
8
+ 2. `icon` is the icon to be shown in the tab, it accept component and it is
9
+ optional.
10
+ 3. You can add more attributes which can be used for custom rendering in the tab
11
+ header or content.
12
+
13
+ ### Options
14
+
15
+ Currently, it has only one option `indicatorLeft` which is used to set the left
16
+ position of the indicator in case of custom rendering. It is optional and
17
+ default value is `20`.
18
+
19
+ ## v-model
20
+
21
+ It is used to set the active tab or change the active tab. It is required.
@@ -27,8 +27,8 @@
27
27
  </Tab>
28
28
  <div
29
29
  ref="indicator"
30
- class="absolute -bottom-px h-px bg-gray-900"
31
- :style="{ left: `${indicatorLeftValue}px` }"
30
+ class="absolute -bottom-px h-px bg-gray-900 transition-all duration-300 ease-in-out"
31
+ :style="{ left: `${indicatorLeft}px` }"
32
32
  />
33
33
  </TabList>
34
34
  <TabPanels class="flex flex-1 overflow-hidden">
@@ -45,7 +45,6 @@
45
45
 
46
46
  <script setup>
47
47
  import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'
48
- import { TransitionPresets, useTransition } from '@vueuse/core'
49
48
  import { ref, watch, computed, onMounted, nextTick } from 'vue'
50
49
 
51
50
  const props = defineProps({
@@ -57,6 +56,12 @@ const props = defineProps({
57
56
  type: Number,
58
57
  default: 0,
59
58
  },
59
+ options: {
60
+ type: Object,
61
+ default: () => ({
62
+ indicatorLeft: 20,
63
+ }),
64
+ },
60
65
  })
61
66
 
62
67
  const emit = defineEmits(['update:modelValue'])
@@ -70,12 +75,7 @@ const tabRef = ref([])
70
75
  const indicator = ref(null)
71
76
  const tabsLength = ref(props.tabs?.length)
72
77
 
73
- let indicatorLeft = ref(0)
74
-
75
- const indicatorLeftValue = useTransition(indicatorLeft, {
76
- duration: 250,
77
- ease: TransitionPresets.easeOutCubic,
78
- })
78
+ const indicatorLeft = ref(props.options?.indicatorLeft)
79
79
 
80
80
  function moveIndicator(index) {
81
81
  if (index >= tabsLength.value) {
@@ -28,6 +28,8 @@ export function createDocumentResource(options, vm) {
28
28
  getConfig('defaultDocUpdateUrl') || 'frappe.client.set_value'
29
29
  let defaultDocDeleteUrl =
30
30
  getConfig('defaultDocDeleteUrl') || 'frappe.client.delete'
31
+ let defaultRunDocMethodUrl =
32
+ getConfig('defaultRunDocMethodUrl') || 'run_doc_method'
31
33
 
32
34
  let setValueOptions = {
33
35
  url: defaultDocUpdateUrl,
@@ -153,7 +155,7 @@ export function createDocumentResource(options, vm) {
153
155
  let { method, onSuccess, ...otherOptions } = methodOptions
154
156
  out[methodKey] = createResource(
155
157
  {
156
- url: 'run_doc_method',
158
+ url: defaultRunDocMethodUrl,
157
159
  makeParams(values) {
158
160
  return {
159
161
  dt: out.doctype,
@@ -30,6 +30,8 @@ export function createListResource(options, vm) {
30
30
  getConfig('defaultDocUpdateUrl') || 'frappe.client.set_value'
31
31
  let defaultDocDeleteUrl =
32
32
  getConfig('defaultDocDeleteUrl') || 'frappe.client.delete'
33
+ let defaultRunDocMethodUrl =
34
+ getConfig('defaultRunDocMethodUrl') || 'run_doc_method'
33
35
 
34
36
  let out = reactive({
35
37
  doctype: options.doctype,
@@ -165,7 +167,7 @@ export function createListResource(options, vm) {
165
167
  ),
166
168
  runDocMethod: createResource(
167
169
  {
168
- url: 'run_doc_method',
170
+ url: defaultRunDocMethodUrl,
169
171
  makeParams({ method, name, ...values }) {
170
172
  return {
171
173
  dt: out.doctype,
@@ -109,12 +109,16 @@ class FileUploadHandler {
109
109
  form_data.append('file_url', options.file_url)
110
110
  }
111
111
 
112
- if (options.doctype && options.docname) {
112
+ if (options.doctype) {
113
113
  form_data.append('doctype', options.doctype)
114
+ }
115
+
116
+ if (options.docname) {
114
117
  form_data.append('docname', options.docname)
115
- if (options.fieldname) {
116
- form_data.append('fieldname', options.fieldname)
117
- }
118
+ }
119
+
120
+ if (options.fieldname) {
121
+ form_data.append('fieldname', options.fieldname)
118
122
  }
119
123
 
120
124
  if (options.method) {