frappe-ui 0.1.174 → 0.1.176

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.174",
3
+ "version": "0.1.176",
4
4
  "description": "A set of components and utilities for rapid UI development",
5
5
  "main": "./src/index.ts",
6
6
  "type": "module",
@@ -35,27 +35,29 @@
35
35
  "@popperjs/core": "^2.11.2",
36
36
  "@tailwindcss/forms": "^0.5.3",
37
37
  "@tailwindcss/typography": "^0.5.16",
38
- "@tiptap/core": "^2.11.7",
39
- "@tiptap/extension-code-block": "^2.11.9",
40
- "@tiptap/extension-code-block-lowlight": "^2.11.5",
41
- "@tiptap/extension-color": "^2.0.3",
42
- "@tiptap/extension-heading": "^2.12.0",
43
- "@tiptap/extension-highlight": "^2.0.3",
44
- "@tiptap/extension-image": "^2.0.3",
45
- "@tiptap/extension-link": "^2.0.3",
46
- "@tiptap/extension-mention": "^2.0.3",
47
- "@tiptap/extension-placeholder": "^2.0.3",
48
- "@tiptap/extension-table": "^2.0.3",
49
- "@tiptap/extension-table-cell": "^2.0.3",
50
- "@tiptap/extension-table-header": "^2.0.3",
51
- "@tiptap/extension-table-row": "^2.0.3",
52
- "@tiptap/extension-text-align": "^2.0.3",
53
- "@tiptap/extension-text-style": "^2.0.3",
54
- "@tiptap/extension-typography": "^2.0.3",
55
- "@tiptap/pm": "^2.0.3",
56
- "@tiptap/starter-kit": "^2.0.3",
57
- "@tiptap/suggestion": "^2.0.3",
58
- "@tiptap/vue-3": "^2.0.3",
38
+ "@tiptap/core": "^2.26.1",
39
+ "@tiptap/extension-code-block": "^2.26.1",
40
+ "@tiptap/extension-code-block-lowlight": "^2.26.1",
41
+ "@tiptap/extension-color": "^2.26.1",
42
+ "@tiptap/extension-heading": "^2.26.1",
43
+ "@tiptap/extension-highlight": "^2.26.1",
44
+ "@tiptap/extension-image": "^2.26.1",
45
+ "@tiptap/extension-link": "^2.26.1",
46
+ "@tiptap/extension-mention": "^2.26.1",
47
+ "@tiptap/extension-placeholder": "^2.26.1",
48
+ "@tiptap/extension-table": "^2.26.1",
49
+ "@tiptap/extension-table-cell": "^2.26.1",
50
+ "@tiptap/extension-table-header": "^2.26.1",
51
+ "@tiptap/extension-table-row": "^2.26.1",
52
+ "@tiptap/extension-task-item": "^2.26.1",
53
+ "@tiptap/extension-task-list": "^2.26.1",
54
+ "@tiptap/extension-text-align": "^2.26.1",
55
+ "@tiptap/extension-text-style": "^2.26.1",
56
+ "@tiptap/extension-typography": "^2.26.1",
57
+ "@tiptap/pm": "^2.26.1",
58
+ "@tiptap/starter-kit": "^2.26.1",
59
+ "@tiptap/suggestion": "^2.26.1",
60
+ "@tiptap/vue-3": "^2.26.1",
59
61
  "@vueuse/core": "^10.4.1",
60
62
  "dayjs": "^1.11.13",
61
63
  "dompurify": "^3.2.6",
@@ -69,14 +71,12 @@
69
71
  "marked": "^15.0.12",
70
72
  "ora": "5.4.1",
71
73
  "prettier": "^3.3.2",
72
- "prosemirror-model": "^1.25.1",
73
- "prosemirror-state": "^1.4.3",
74
- "prosemirror-view": "^1.39.2",
75
74
  "radix-vue": "^1.5.3",
76
75
  "reka-ui": "^2.0.2",
77
76
  "socket.io-client": "^4.5.1",
78
77
  "tippy.js": "^6.3.7",
79
78
  "typescript": "^5.0.2",
79
+ "unplugin-auto-import": "^19.3.0",
80
80
  "unplugin-icons": "^22.1.0",
81
81
  "unplugin-vue-components": "^28.4.1"
82
82
  },
@@ -99,6 +99,12 @@
99
99
  "vue": "^3.3.0",
100
100
  "vue-router": "^4.1.6"
101
101
  },
102
+ "resolutions": {
103
+ "prosemirror-model": "1.25.2",
104
+ "prosemirror-state": "1.4.3",
105
+ "prosemirror-view": "1.40.0",
106
+ "prosemirror-transform": "1.10.4"
107
+ },
102
108
  "lint-staged": {
103
109
  "*.{js,css,md,vue}": "prettier --write"
104
110
  }
@@ -20,6 +20,7 @@ const crmSidebar = reactive({
20
20
  header: {
21
21
  title: 'Frappe CRM',
22
22
  subtitle: 'Jane Doe',
23
+ logo: 'https://raw.githubusercontent.com/frappe/crm/develop/.github/logo.svg',
23
24
  menuItems: [
24
25
  { label: 'Toggle Theme', icon: Moon, onClick: toggleTheme },
25
26
  { label: 'Help', to: '/help', icon: Settings, onClick: () => alert('Help clicked!') },
@@ -8,8 +8,13 @@
8
8
  :isCollapsed="isCollapsed"
9
9
  :title="props.header.title"
10
10
  :subtitle="props.header.subtitle"
11
+ :logo="props.header.logo"
11
12
  :menu-items="props.header.menuItems"
12
- />
13
+ >
14
+ <template #header-logo>
15
+ <slot name="logo"></slot>
16
+ </template>
17
+ </SidebarHeader>
13
18
 
14
19
  <SidebarSection
15
20
  v-for="section in props.sections"
@@ -11,11 +11,22 @@
11
11
  : 'px-2 hover:bg-surface-gray-3'
12
12
  "
13
13
  >
14
- <slot name="logo">
15
- <div class="w-8 h-8 rounded bg-surface-gray-4 flex items-center justify-center text-ink-gray-7">
16
- {{ props.title.charAt(0).toUpperCase() }}
17
- </div>
18
- </slot>
14
+ <div class="w-8 h-8 rounded overflow-hidden">
15
+ <slot name="logo">
16
+ <img
17
+ v-if="props.logo"
18
+ :src="props.logo"
19
+ class="w-full h-full object-cover"
20
+ alt="Logo"
21
+ />
22
+ <div
23
+ v-else
24
+ class="w-full h-full bg-surface-gray-4 flex items-center justify-center text-ink-gray-7"
25
+ >
26
+ {{ props.title.charAt(0).toUpperCase() }}
27
+ </div>
28
+ </slot>
29
+ </div>
19
30
  <div
20
31
  class="flex flex-1 flex-col text-left duration-300 ease-in-out truncate"
21
32
  :class="
@@ -23,8 +34,10 @@
23
34
  ? 'ml-0 w-0 overflow-hidden opacity-0'
24
35
  : 'ml-2 w-auto opacity-100'
25
36
  "
26
- >
27
- <div class="text-base font-medium text-ink-gray-8 leading-none">{{ props.title }}</div>
37
+ >
38
+ <div class="text-base font-medium text-ink-gray-8 leading-none">
39
+ {{ props.title }}
40
+ </div>
28
41
  <div class="mt-1 text-sm text-ink-gray-6 leading-none">
29
42
  {{ props.subtitle }}
30
43
  </div>
@@ -36,8 +49,8 @@
36
49
  ? 'ml-0 w-0 overflow-hidden opacity-0'
37
50
  : 'ml-2 w-auto opacity-100'
38
51
  "
39
- >
40
- <LucideChevronDown class="h-4 w-4 text-ink-gray-7"/>
52
+ >
53
+ <LucideChevronDown class="h-4 w-4 text-ink-gray-7" />
41
54
  </div>
42
55
  </button>
43
56
  </template>
@@ -45,11 +58,11 @@
45
58
  </template>
46
59
 
47
60
  <script setup lang="ts">
48
- import { inject } from 'vue';
49
- import LucideChevronDown from '~icons/lucide/chevron-down';
50
- import { SidebarHeaderProps } from './types';
51
- import Dropdown from '../Dropdown/Dropdown.vue';
61
+ import { inject } from 'vue'
62
+ import LucideChevronDown from '~icons/lucide/chevron-down'
63
+ import Dropdown from '../Dropdown/Dropdown.vue'
64
+ import { SidebarHeaderProps } from './types'
52
65
 
53
- const props = defineProps<SidebarHeaderProps>();
54
- const isCollapsed = inject('isSidebarCollapsed', false);
66
+ const props = defineProps<SidebarHeaderProps>()
67
+ const isCollapsed = inject('isSidebarCollapsed', false)
55
68
  </script>
@@ -3,6 +3,7 @@ import { RouteLocationRaw } from 'vue-router'
3
3
  export type SidebarHeaderProps = {
4
4
  title: string
5
5
  subtitle?: string
6
+ logo?: string
6
7
  menuItems?: {
7
8
  label: string
8
9
  icon: any // Icon component
@@ -28,14 +28,15 @@
28
28
  </button>
29
29
  </template>
30
30
  <template #body="{ close }">
31
- <ul class="rounded border bg-surface-white p-1 shadow-md">
31
+ <ul
32
+ class="p-1.5 mt-2 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
33
+ >
32
34
  <li
33
- class="w-full"
34
35
  v-for="option in button"
35
36
  v-show="option.isDisabled ? !option.isDisabled(editor) : true"
36
37
  >
37
38
  <button
38
- class="w-full rounded px-2 py-1 text-left text-base hover:bg-surface-menu-bar"
39
+ class="h-7 rounded px-2 text-base flex items-center gap-2 hover:bg-surface-gray-3"
39
40
  @click="
40
41
  () => {
41
42
  onButtonClick(option)
@@ -43,7 +44,16 @@
43
44
  }
44
45
  "
45
46
  >
46
- {{ option.label }}
47
+ <component
48
+ v-if="option.icon"
49
+ :is="option.icon"
50
+ class="size-4 flex-shrink-0 text-ink-gray-6"
51
+ />
52
+ <span
53
+ v-if="option.label"
54
+ class="whitespace-nowrap text-ink-gray-7"
55
+ >{{ option.label }}</span
56
+ >
47
57
  </button>
48
58
  </li>
49
59
  </ul>
@@ -54,11 +64,12 @@
54
64
  <template v-slot="componentSlotProps">
55
65
  <button
56
66
  class="flex rounded p-1 text-ink-gray-8 transition-colors"
57
- :class="
67
+ :class="[
58
68
  button.isActive(editor) || componentSlotProps?.isActive
59
- ? 'bg-surface-gray-2'
60
- : 'hover:bg-surface-gray-2'
61
- "
69
+ ? 'bg-surface-gray-3'
70
+ : 'hover:bg-surface-gray-2',
71
+ button.class,
72
+ ]"
62
73
  @click="
63
74
  componentSlotProps?.onClick
64
75
  ? componentSlotProps.onClick(button)
@@ -11,11 +11,11 @@
11
11
  :buttons="fixedMenu"
12
12
  />
13
13
  <TextEditorFloatingMenu :buttons="floatingMenu" />
14
- <slot name="top" />
14
+ <slot name="top" :editor />
15
15
  <slot name="editor" :editor="editor">
16
16
  <EditorContent :editor="editor" />
17
17
  </slot>
18
- <slot name="bottom" />
18
+ <slot name="bottom" :editor />
19
19
  </div>
20
20
  </template>
21
21
 
@@ -48,6 +48,8 @@ import VideoExtension from './video-extension'
48
48
  import LinkExtension from './link-extension'
49
49
  import Typography from '@tiptap/extension-typography'
50
50
  import TextStyle from '@tiptap/extension-text-style'
51
+ import TaskItem from '@tiptap/extension-task-item'
52
+ import TaskList from '@tiptap/extension-task-list'
51
53
  import NamedColorExtension from './extensions/color'
52
54
  import NamedHighlightExtension from './extensions/highlight'
53
55
  import { common, createLowlight } from 'lowlight'
@@ -79,6 +81,7 @@ const props = withDefaults(defineProps<TextEditorProps>(), {
79
81
  placeholder: '',
80
82
  editorClass: '',
81
83
  editable: true,
84
+ autofocus: false,
82
85
  bubbleMenu: false,
83
86
  bubbleMenuOptions: () => ({}),
84
87
  fixedMenu: false,
@@ -117,7 +120,7 @@ watch(
117
120
  editor.value.commands.setContent(val)
118
121
  }
119
122
  }
120
- },
123
+ }
121
124
  )
122
125
 
123
126
  watch(
@@ -126,7 +129,7 @@ watch(
126
129
  if (editor.value) {
127
130
  editor.value.setEditable(value)
128
131
  }
129
- },
132
+ }
130
133
  )
131
134
 
132
135
  watch(
@@ -138,7 +141,7 @@ watch(
138
141
  })
139
142
  }
140
143
  },
141
- { deep: true },
144
+ { deep: true }
142
145
  )
143
146
 
144
147
  onMounted(() => {
@@ -146,6 +149,7 @@ onMounted(() => {
146
149
  content: props.content || null,
147
150
  editorProps: editorProps.value,
148
151
  editable: props.editable,
152
+ autofocus: props.autofocus,
149
153
  extensions: [
150
154
  StarterKit.configure({
151
155
  ...props.starterkitOptions,
@@ -161,6 +165,10 @@ onMounted(() => {
161
165
  Table.configure({
162
166
  resizable: true,
163
167
  }),
168
+ TaskList,
169
+ TaskItem.configure({
170
+ nested: true,
171
+ }),
164
172
  TableRow,
165
173
  TableHeader,
166
174
  TableCell,
@@ -230,7 +238,7 @@ onBeforeUnmount(() => {
230
238
 
231
239
  provide(
232
240
  'editor',
233
- computed(() => editor.value),
241
+ computed(() => editor.value)
234
242
  )
235
243
 
236
244
  defineExpose({
@@ -302,6 +310,44 @@ img.ProseMirror-selectednode {
302
310
  pointer-events: none;
303
311
  }
304
312
 
313
+ .ProseMirror ul[data-type='taskList'] {
314
+ list-style: none;
315
+ padding: 0;
316
+
317
+ li {
318
+ align-items: flex-start;
319
+ display: flex;
320
+ margin: 0;
321
+
322
+ > label {
323
+ flex: 0 0 auto;
324
+ margin-right: 0.5rem;
325
+ margin-top: 0.25rem;
326
+ height: 1.5em;
327
+ display: flex;
328
+ align-items: center;
329
+ user-select: none;
330
+ }
331
+
332
+ > div {
333
+ flex: 1 1 auto;
334
+ margin-bottom: 0;
335
+
336
+ > p {
337
+ margin: 0.25rem 0;
338
+ }
339
+ }
340
+ }
341
+
342
+ input[type='checkbox'] {
343
+ cursor: pointer;
344
+ width: 14px;
345
+ height: 14px;
346
+ border-radius: 4px;
347
+ color: theme('colors.gray.900');
348
+ }
349
+ }
350
+
305
351
  .resize-cursor {
306
352
  cursor: ew-resize;
307
353
  cursor: col-resize;
@@ -37,11 +37,13 @@ export default {
37
37
  'Separator',
38
38
  'Bold',
39
39
  'Italic',
40
+ 'Strikethrough',
40
41
  'FontColor',
41
42
  'Link',
42
43
  'Separator',
43
44
  'Bullet List',
44
45
  'Numbered List',
46
+ 'Task List',
45
47
  'Separator',
46
48
  'Align Left',
47
49
  'Align Center',
@@ -33,6 +33,7 @@ export default {
33
33
  'Separator',
34
34
  'Bullet List',
35
35
  'Numbered List',
36
+ 'Task List',
36
37
  'Separator',
37
38
  'Align Left',
38
39
  'Align Center',
@@ -47,6 +47,7 @@ export default {
47
47
  'Heading 3',
48
48
  'Bullet List',
49
49
  'Numbered List',
50
+ 'Task List',
50
51
  'Blockquote',
51
52
  'Code',
52
53
  'Horizontal Rule',
@@ -9,12 +9,14 @@ import Text from './icons/text.vue'
9
9
  import Bold from './icons/bold.vue'
10
10
  import Italic from './icons/italic.vue'
11
11
  import Underline from './icons/underline.vue'
12
+ import Strikethrough from './icons/strikethrough.vue'
12
13
  import AlignCenter from './icons/align-center.vue'
13
14
  import AlignLeft from './icons/align-left.vue'
14
15
  import AlignRight from './icons/align-right.vue'
15
16
  import FontColor from './icons/font-color.vue'
16
17
  import ListOrdered from './icons/list-ordered.vue'
17
18
  import ListUnordered from './icons/list-unordered.vue'
19
+ import ListTask from './icons/list-task.vue'
18
20
  import DoubleQuotes from './icons/double-quotes-r.vue'
19
21
  import CodeView from './icons/code-view.vue'
20
22
  import Link from './icons/link.vue'
@@ -98,6 +100,12 @@ export default {
98
100
  action: (editor) => editor.chain().focus().toggleUnderline().run(),
99
101
  isActive: (editor) => editor.isActive('underline'),
100
102
  },
103
+ Strikethrough: {
104
+ label: 'Strikethrough',
105
+ icon: Strikethrough,
106
+ action: (editor) => editor.chain().focus().toggleStrike().run(),
107
+ isActive: (editor) => editor.isActive('strike'),
108
+ },
101
109
  'Bullet List': {
102
110
  label: 'Bullet List',
103
111
  icon: ListUnordered,
@@ -110,6 +118,12 @@ export default {
110
118
  action: (editor) => editor.chain().focus().toggleOrderedList().run(),
111
119
  isActive: (editor) => editor.isActive('orderedList'),
112
120
  },
121
+ 'Task List': {
122
+ label: 'Task List',
123
+ icon: ListTask,
124
+ action: (editor) => editor.chain().focus().toggleTaskList().run(),
125
+ isActive: (editor) => editor.isActive('taskList'),
126
+ },
113
127
  'Align Center': {
114
128
  label: 'Align Center',
115
129
  icon: AlignCenter,
@@ -1,7 +1,7 @@
1
1
  import { Extension } from '@tiptap/core'
2
2
  import { Plugin, PluginKey } from '@tiptap/pm/state'
3
3
  import { DOMParser } from '@tiptap/pm/model'
4
- import { EditorView } from 'prosemirror-view'
4
+ import { EditorView } from '@tiptap/pm/view'
5
5
  import { detectMarkdown, markdownToHTML } from '../../../utils/markdown'
6
6
  import { processMultipleImages } from './image/image-extension'
7
7
 
@@ -1,4 +1,4 @@
1
- import { PluginKey } from 'prosemirror-state'
1
+ import { PluginKey } from '@tiptap/pm/state'
2
2
  import {
3
3
  BaseSuggestionItem,
4
4
  createSuggestionExtension,
@@ -5,8 +5,8 @@ import {
5
5
  } from '@tiptap/core'
6
6
  import { VueNodeViewRenderer } from '@tiptap/vue-3'
7
7
  import ImageNodeView from './ImageNodeView.vue'
8
- import { Plugin, Selection, Transaction, EditorState } from 'prosemirror-state'
9
- import { EditorView } from 'prosemirror-view'
8
+ import { Plugin, Selection, Transaction, EditorState } from '@tiptap/pm/state'
9
+ import { EditorView } from '@tiptap/pm/view'
10
10
  import { Node } from '@tiptap/pm/model'
11
11
  import { fileToBase64 } from '../../../../index'
12
12
  import { UploadedFile } from '../../../../utils/useFileUpload'
@@ -1,5 +1,5 @@
1
1
  import { Editor, Range } from '@tiptap/core'
2
- import { PluginKey } from 'prosemirror-state'
2
+ import { PluginKey } from '@tiptap/pm/state'
3
3
  import {
4
4
  createSuggestionExtension,
5
5
  type BaseSuggestionItem,
@@ -11,6 +11,7 @@ import Heading2 from '~icons/lucide/heading-2'
11
11
  import Heading3 from '~icons/lucide/heading-3'
12
12
  import List from '~icons/lucide/list'
13
13
  import ListOrdered from '~icons/lucide/list-ordered'
14
+ import ListTask from '~icons/lucide/list-checks'
14
15
  import Code from '~icons/lucide/code'
15
16
  import Quote from '~icons/lucide/quote'
16
17
  import Image from '~icons/lucide/image'
@@ -67,12 +68,19 @@ const getCommands = (): CommandItem[] => [
67
68
  },
68
69
  },
69
70
  {
70
- title: 'Ordered List',
71
+ title: 'Numbered List',
71
72
  icon: ListOrdered,
72
73
  command: ({ editor, range }: CommandExecutionProps) => {
73
74
  editor.chain().focus().deleteRange(range).toggleOrderedList().run()
74
75
  },
75
76
  },
77
+ {
78
+ title: 'Task List',
79
+ icon: ListTask,
80
+ command: ({ editor, range }: CommandExecutionProps) => {
81
+ editor.chain().focus().deleteRange(range).toggleTaskList().run()
82
+ },
83
+ },
76
84
  {
77
85
  title: 'Code Block',
78
86
  icon: Code,
@@ -4,7 +4,7 @@ import Suggestion, {
4
4
  SuggestionOptions,
5
5
  SuggestionProps,
6
6
  } from '@tiptap/suggestion'
7
- import { PluginKey } from 'prosemirror-state'
7
+ import { PluginKey } from '@tiptap/pm/state'
8
8
  import tippy, { Instance as TippyInstance, Props as TippyProps } from 'tippy.js'
9
9
  import { Component as VueComponent } from 'vue'
10
10
 
@@ -1,5 +1,5 @@
1
1
  import { Node, mergeAttributes, Range, Editor } from '@tiptap/core'
2
- import { PluginKey } from 'prosemirror-state'
2
+ import { PluginKey } from '@tiptap/pm/state'
3
3
  import {
4
4
  createSuggestionExtension,
5
5
  BaseSuggestionItem,
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="24"
5
+ height="24"
6
+ viewBox="0 0 24 24"
7
+ fill="none"
8
+ stroke="currentColor"
9
+ stroke-width="2"
10
+ stroke-linecap="round"
11
+ stroke-linejoin="round"
12
+ class="lucide lucide-list-checks-icon lucide-list-checks"
13
+ >
14
+ <path d="m3 17 2 2 4-4" />
15
+ <path d="m3 7 2 2 4-4" />
16
+ <path d="M13 6h8" />
17
+ <path d="M13 12h8" />
18
+ <path d="M13 18h8" />
19
+ </svg>
20
+ </template>
@@ -1,5 +1,5 @@
1
1
  import { Extension } from '@tiptap/core'
2
- import { Plugin, PluginKey } from 'prosemirror-state'
2
+ import { Plugin, PluginKey } from '@tiptap/pm/state'
3
3
  import { createApp, h } from 'vue'
4
4
  import ImageViewerModal from './ImageViewerModal.vue'
5
5
 
@@ -2,8 +2,8 @@ import { createApp, h } from 'vue'
2
2
  import Link from '@tiptap/extension-link'
3
3
  import tippy, { type Instance as TippyInstance } from 'tippy.js'
4
4
  import { getMarkRange, Range, Editor } from '@tiptap/core'
5
- import { MarkType, Mark as ProseMirrorMark } from 'prosemirror-model'
6
- import { Plugin, PluginKey } from 'prosemirror-state'
5
+ import { MarkType, Mark as ProseMirrorMark } from '@tiptap/pm/model'
6
+ import { Plugin, PluginKey } from '@tiptap/pm/state'
7
7
  import EditLink from './EditLink.vue'
8
8
  import { linkPasteHandler } from './linkPasteHandler'
9
9
 
@@ -1,6 +1,6 @@
1
1
  import { Node, mergeAttributes, Editor } from '@tiptap/core'
2
2
  import { Node as ProseMirrorNode } from '@tiptap/pm/model'
3
- import { EditorView } from 'prosemirror-view'
3
+ import { EditorView } from '@tiptap/pm/view'
4
4
  import { UploadedFile } from '../../utils/useFileUpload'
5
5
 
6
6
  export interface VideoOptions {
@@ -398,7 +398,7 @@ export default plugin(
398
398
  }),
399
399
  },
400
400
  },
401
- },
401
+ }
402
402
  )
403
403
 
404
404
  function em(pixels, base = 16) {
@@ -1,18 +1,21 @@
1
1
  import * as LucideIcons from 'lucide-static'
2
+ import AutoImport from 'unplugin-auto-import/vite'
2
3
  import Icons from 'unplugin-icons/vite'
3
4
  import Components from 'unplugin-vue-components/vite'
4
5
  import IconsResolver from 'unplugin-icons/resolver'
5
6
 
6
7
  export function lucideIcons() {
8
+ const resolverObj = {
9
+ resolvers: [
10
+ IconsResolver({
11
+ prefix: false,
12
+ enabledCollections: ['lucide'],
13
+ }),
14
+ ],
15
+ }
7
16
  return [
8
- Components({
9
- resolvers: [
10
- IconsResolver({
11
- prefix: false,
12
- enabledCollections: ['lucide'],
13
- }),
14
- ],
15
- }),
17
+ AutoImport(resolverObj),
18
+ Components(resolverObj),
16
19
  Icons({
17
20
  customCollections: {
18
21
  lucide: getIcons(),