windly-ui 1.0.1 → 1.0.3

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.
Files changed (123) hide show
  1. package/dist/module.d.mts +3 -0
  2. package/dist/module.json +8 -0
  3. package/dist/module.mjs +26 -0
  4. package/dist/runtime/components/Accordion.d.vue.ts +39 -0
  5. package/{ui-library → dist/runtime}/components/Accordion.vue +44 -70
  6. package/dist/runtime/components/Accordion.vue.d.ts +39 -0
  7. package/dist/runtime/components/Avatar.d.vue.ts +141 -0
  8. package/dist/runtime/components/Avatar.vue +72 -0
  9. package/dist/runtime/components/Avatar.vue.d.ts +141 -0
  10. package/dist/runtime/components/Badge.d.vue.ts +133 -0
  11. package/dist/runtime/components/Badge.vue +99 -0
  12. package/dist/runtime/components/Badge.vue.d.ts +133 -0
  13. package/dist/runtime/components/Breadcrumbs.d.vue.ts +83 -0
  14. package/{ui-library → dist/runtime}/components/Breadcrumbs.vue +37 -59
  15. package/dist/runtime/components/Breadcrumbs.vue.d.ts +83 -0
  16. package/dist/runtime/components/Button.d.vue.ts +199 -0
  17. package/dist/runtime/components/Button.vue +125 -0
  18. package/dist/runtime/components/Button.vue.d.ts +199 -0
  19. package/dist/runtime/components/Card.d.vue.ts +83 -0
  20. package/{ui-library → dist/runtime}/components/Card.vue +26 -39
  21. package/dist/runtime/components/Card.vue.d.ts +83 -0
  22. package/dist/runtime/components/Checkbox.d.vue.ts +190 -0
  23. package/{ui-library → dist/runtime}/components/Checkbox.vue +45 -68
  24. package/dist/runtime/components/Checkbox.vue.d.ts +190 -0
  25. package/dist/runtime/components/CodeBlock.d.vue.ts +16 -0
  26. package/dist/runtime/components/CodeBlock.vue +75 -0
  27. package/dist/runtime/components/CodeBlock.vue.d.ts +16 -0
  28. package/dist/runtime/components/ColorPicker.d.vue.ts +91 -0
  29. package/dist/runtime/components/ColorPicker.vue +244 -0
  30. package/dist/runtime/components/ColorPicker.vue.d.ts +91 -0
  31. package/dist/runtime/components/Date.d.vue.ts +137 -0
  32. package/dist/runtime/components/Date.vue +201 -0
  33. package/dist/runtime/components/Date.vue.d.ts +137 -0
  34. package/dist/runtime/components/Dialog.d.vue.ts +103 -0
  35. package/{ui-library → dist/runtime}/components/Dialog.vue +30 -65
  36. package/dist/runtime/components/Dialog.vue.d.ts +103 -0
  37. package/dist/runtime/components/Divider.d.vue.ts +51 -0
  38. package/dist/runtime/components/Divider.vue +52 -0
  39. package/dist/runtime/components/Divider.vue.d.ts +51 -0
  40. package/dist/runtime/components/Drawer.d.vue.ts +30 -0
  41. package/dist/runtime/components/Drawer.vue +43 -0
  42. package/dist/runtime/components/Drawer.vue.d.ts +30 -0
  43. package/dist/runtime/components/Dropdown.d.vue.ts +34 -0
  44. package/dist/runtime/components/Dropdown.vue +127 -0
  45. package/dist/runtime/components/Dropdown.vue.d.ts +34 -0
  46. package/dist/runtime/components/FileUploader.d.vue.ts +58 -0
  47. package/dist/runtime/components/FileUploader.vue +202 -0
  48. package/dist/runtime/components/FileUploader.vue.d.ts +58 -0
  49. package/dist/runtime/components/Icon.d.vue.ts +41 -0
  50. package/dist/runtime/components/Icon.vue +66 -0
  51. package/dist/runtime/components/Icon.vue.d.ts +41 -0
  52. package/dist/runtime/components/Image.d.vue.ts +77 -0
  53. package/dist/runtime/components/Image.vue +61 -0
  54. package/dist/runtime/components/Image.vue.d.ts +77 -0
  55. package/dist/runtime/components/Input.d.vue.ts +66 -0
  56. package/dist/runtime/components/Input.vue +233 -0
  57. package/dist/runtime/components/Input.vue.d.ts +66 -0
  58. package/dist/runtime/components/Radio.d.vue.ts +41 -0
  59. package/dist/runtime/components/Radio.vue +222 -0
  60. package/dist/runtime/components/Radio.vue.d.ts +41 -0
  61. package/dist/runtime/components/ScrollArea.d.vue.ts +79 -0
  62. package/dist/runtime/components/ScrollArea.vue +36 -0
  63. package/dist/runtime/components/ScrollArea.vue.d.ts +79 -0
  64. package/dist/runtime/components/Select.d.vue.ts +43 -0
  65. package/dist/runtime/components/Select.vue +200 -0
  66. package/dist/runtime/components/Select.vue.d.ts +43 -0
  67. package/dist/runtime/components/Stepper.d.vue.ts +46 -0
  68. package/dist/runtime/components/Stepper.vue +218 -0
  69. package/dist/runtime/components/Stepper.vue.d.ts +46 -0
  70. package/dist/runtime/components/TabPanel.d.vue.ts +17 -0
  71. package/dist/runtime/components/TabPanel.vue +21 -0
  72. package/dist/runtime/components/TabPanel.vue.d.ts +17 -0
  73. package/dist/runtime/components/Table.d.vue.ts +40 -0
  74. package/dist/runtime/components/Table.vue +92 -0
  75. package/dist/runtime/components/Table.vue.d.ts +40 -0
  76. package/dist/runtime/components/Tabs.d.vue.ts +20 -0
  77. package/dist/runtime/components/Tabs.vue +62 -0
  78. package/dist/runtime/components/Tabs.vue.d.ts +20 -0
  79. package/dist/runtime/components/Textarea.d.vue.ts +208 -0
  80. package/dist/runtime/components/Textarea.vue +185 -0
  81. package/dist/runtime/components/Textarea.vue.d.ts +208 -0
  82. package/dist/runtime/components/Toggle.d.vue.ts +36 -0
  83. package/dist/runtime/components/Toggle.vue +173 -0
  84. package/dist/runtime/components/Toggle.vue.d.ts +36 -0
  85. package/dist/runtime/components/Tooltip.d.vue.ts +63 -0
  86. package/dist/runtime/components/Tooltip.vue +144 -0
  87. package/dist/runtime/components/Tooltip.vue.d.ts +63 -0
  88. package/dist/runtime/components/uiProps.d.ts +38 -0
  89. package/{ui-library/components/uiProps.ts → dist/runtime/components/uiProps.js} +2 -2
  90. package/dist/runtime/components/useUiClasses.d.ts +43 -0
  91. package/{ui-library/components/useUiClasses.ts → dist/runtime/components/useUiClasses.js} +25 -60
  92. package/dist/runtime/composables/plugin.d.ts +2 -0
  93. package/dist/runtime/composables/plugin.js +3 -0
  94. package/dist/runtime/tailwind-color.d.ts +2 -0
  95. package/dist/runtime/tailwind-color.js +5859 -0
  96. package/dist/types.d.mts +7 -0
  97. package/package.json +14 -16
  98. package/README.md +0 -208
  99. package/ui-library/components/Avatar.vue +0 -121
  100. package/ui-library/components/Badge.vue +0 -116
  101. package/ui-library/components/Button.vue +0 -154
  102. package/ui-library/components/CodeBlock.vue +0 -99
  103. package/ui-library/components/ColorPicker.vue +0 -302
  104. package/ui-library/components/Date.vue +0 -240
  105. package/ui-library/components/Divider.vue +0 -78
  106. package/ui-library/components/Drawer.vue +0 -67
  107. package/ui-library/components/Dropdown.vue +0 -248
  108. package/ui-library/components/FileUploader.vue +0 -330
  109. package/ui-library/components/Icon.vue +0 -82
  110. package/ui-library/components/Image.vue +0 -78
  111. package/ui-library/components/Input.vue +0 -531
  112. package/ui-library/components/Radio.vue +0 -356
  113. package/ui-library/components/ScrollArea.vue +0 -43
  114. package/ui-library/components/Select.vue +0 -309
  115. package/ui-library/components/Stepper.vue +0 -361
  116. package/ui-library/components/TabPanel.vue +0 -25
  117. package/ui-library/components/Table.vue +0 -152
  118. package/ui-library/components/Tabs.vue +0 -71
  119. package/ui-library/components/Textarea.vue +0 -233
  120. package/ui-library/components/Toggle.vue +0 -319
  121. package/ui-library/components/Tooltip.vue +0 -200
  122. package/ui-library/components/plugin.ts +0 -8
  123. package/ui-library/module.ts +0 -20
@@ -1,67 +0,0 @@
1
- <script setup lang="ts">
2
- defineOptions({
3
- name: 'UIDrawer',
4
- })
5
-
6
- type DrawerDirection = 'left' | 'right'
7
-
8
- interface Props {
9
- isOpen: boolean
10
- direction?: DrawerDirection
11
- background?: string
12
- width?: string
13
- padding?: string
14
- }
15
-
16
- withDefaults(defineProps<Props>(), {
17
- direction: 'right',
18
- background: 'bg-white dark:bg-gray-900',
19
- width: 'w-80',
20
- padding: 'p-6',
21
- })
22
-
23
- const emit = defineEmits<{
24
- close: []
25
- }>()
26
- </script>
27
-
28
- <template>
29
- <div
30
- class="fixed inset-0 z-40 bg-black/40 transition-opacity duration-300"
31
- :class="[
32
- isOpen
33
- ? 'opacity-100 visible'
34
- : 'opacity-0 invisible',
35
- ]"
36
- @click="emit('close')"
37
- />
38
-
39
- <div
40
- class="fixed top-0 bottom-0 z-50 shadow-2xl transition-transform duration-500 ease-in-out"
41
- :class="[
42
- width,
43
- padding,
44
- background,
45
- direction === 'left'
46
- ? 'left-0'
47
- : 'right-0',
48
-
49
- direction === 'left'
50
- ? isOpen
51
- ? 'translate-x-0'
52
- : '-translate-x-full'
53
- : isOpen
54
- ? 'translate-x-0'
55
- : 'translate-x-full',
56
- ]"
57
- >
58
- <button
59
- class="absolute top-4 right-4 text-xl font-bold"
60
- @click="emit('close')"
61
- >
62
-
63
- </button>
64
-
65
- <slot />
66
- </div>
67
- </template>
@@ -1,248 +0,0 @@
1
- <script setup lang="ts">
2
- defineOptions({
3
- name: 'UIDropdown',
4
- })
5
-
6
- import {
7
- computed,
8
- onBeforeUnmount,
9
- onMounted,
10
- ref,
11
- } from 'vue'
12
-
13
- type DropdownAlign =
14
- | 'left'
15
- | 'right'
16
-
17
- type Rounded =
18
- | 'none'
19
- | 'sm'
20
- | 'md'
21
- | 'lg'
22
- | 'xl'
23
- | 'full'
24
-
25
- const props = withDefaults(
26
- defineProps<{
27
- align?: DropdownAlign
28
-
29
- width?: string
30
-
31
- menuBgClass?: string
32
-
33
- rounded?: Rounded
34
-
35
- bordered?: boolean
36
-
37
- borderColor?: string
38
-
39
- flat?: boolean
40
- }>(),
41
- {
42
- align: 'left',
43
-
44
- width: 'w-48',
45
-
46
- menuBgClass:
47
- 'bg-white dark:bg-gray-800',
48
-
49
- rounded: 'xl',
50
-
51
- bordered: false,
52
-
53
- borderColor: 'gray-200',
54
-
55
- flat: false,
56
- },
57
- )
58
-
59
- const isOpen = ref(false)
60
-
61
- const dropdownRef =
62
- ref<HTMLElement | null>(null)
63
-
64
- const isHex = (
65
- val: string,
66
- ): boolean => {
67
- return (
68
- val.startsWith('#') ||
69
- val.startsWith('rgb') ||
70
- val.startsWith('hsl')
71
- )
72
- }
73
-
74
- const toggle = (): void => {
75
- isOpen.value = !isOpen.value
76
- }
77
-
78
- const close = (): void => {
79
- isOpen.value = false
80
- }
81
-
82
- const handleClickOutside = (
83
- event: MouseEvent,
84
- ): void => {
85
- const target =
86
- event.target as Node
87
-
88
- if (
89
- dropdownRef.value &&
90
- !dropdownRef.value.contains(
91
- target,
92
- )
93
- ) {
94
- close()
95
- }
96
- }
97
-
98
- onMounted(() => {
99
- document.addEventListener(
100
- 'click',
101
- handleClickOutside,
102
- )
103
- })
104
-
105
- onBeforeUnmount(() => {
106
- document.removeEventListener(
107
- 'click',
108
- handleClickOutside,
109
- )
110
- })
111
-
112
- const roundedClass = computed(
113
- () => {
114
- const map: Record<
115
- Rounded,
116
- string
117
- > = {
118
- none: 'rounded-none',
119
-
120
- sm: 'rounded-sm',
121
-
122
- md: 'rounded-md',
123
-
124
- lg: 'rounded-lg',
125
-
126
- xl: 'rounded-xl',
127
-
128
- full: 'rounded-full',
129
- }
130
-
131
- return map[props.rounded]
132
- },
133
- )
134
-
135
- const dropdownClasses =
136
- computed(() => [
137
- 'absolute mt-2 z-50 transition-all overflow-hidden',
138
-
139
- props.align === 'right'
140
- ? 'right-0'
141
- : 'left-0',
142
-
143
- props.width,
144
-
145
- roundedClass.value,
146
-
147
- props.bordered &&
148
- !isHex(props.borderColor)
149
- ? `border border-${props.borderColor}`
150
- : '',
151
-
152
- props.flat
153
- ? 'shadow-none'
154
- : 'shadow-lg',
155
- ])
156
-
157
- const dropdownStyle = computed(
158
- () => {
159
- const style: Record<
160
- string,
161
- string
162
- > = {}
163
-
164
- if (
165
- props.bordered &&
166
- isHex(props.borderColor)
167
- ) {
168
- style.border =
169
- `1px solid ${props.borderColor}`
170
- }
171
-
172
- return style
173
- },
174
- )
175
-
176
- const menuClasses = computed(
177
- () => [
178
- 'p-2',
179
-
180
- roundedClass.value,
181
-
182
- props.menuBgClass,
183
- ],
184
- )
185
- </script>
186
-
187
- <template>
188
- <div
189
- ref="dropdownRef"
190
- class="relative inline-block"
191
- >
192
- <!-- Trigger -->
193
- <div @click="toggle">
194
- <slot name="trigger" />
195
- </div>
196
-
197
- <!-- Dropdown -->
198
- <transition
199
- name="fade-slide"
200
- >
201
- <div
202
- v-if="isOpen"
203
- :class="
204
- dropdownClasses
205
- "
206
- :style="
207
- dropdownStyle
208
- "
209
- >
210
- <div
211
- :class="
212
- menuClasses
213
- "
214
- >
215
- <slot name="menu" />
216
- </div>
217
- </div>
218
- </transition>
219
- </div>
220
- </template>
221
-
222
- <style scoped>
223
- .fade-slide-enter-active,
224
- .fade-slide-leave-active {
225
- transition:
226
- all 200ms ease;
227
- }
228
-
229
- .fade-slide-enter-from {
230
- opacity: 0;
231
- transform: translateY(-8px);
232
- }
233
-
234
- .fade-slide-enter-to {
235
- opacity: 1;
236
- transform: translateY(0);
237
- }
238
-
239
- .fade-slide-leave-from {
240
- opacity: 1;
241
- transform: translateY(0);
242
- }
243
-
244
- .fade-slide-leave-to {
245
- opacity: 0;
246
- transform: translateY(-8px);
247
- }
248
- </style>
@@ -1,330 +0,0 @@
1
- <script setup lang="ts">
2
- import { computed, ref } from 'vue'
3
-
4
- defineOptions({
5
- name: 'UIFileUploader',
6
- })
7
-
8
- interface UploadedFile {
9
- file: File
10
- name: string
11
- size: number
12
- type: string
13
- }
14
-
15
- type Separator =
16
- | 'solid'
17
- | 'dashed'
18
- | 'dotted'
19
-
20
- type Rounded =
21
- | 'none'
22
- | 'sm'
23
- | 'md'
24
- | 'lg'
25
- | 'xl'
26
-
27
- const props = withDefaults(
28
- defineProps<{
29
- modelValue?: UploadedFile[]
30
- header?: string
31
- subHeader?: string
32
- fileType?: string
33
- multiple?: boolean
34
- disabled?: boolean
35
- bordered?: boolean
36
- flat?: boolean
37
- rounded?: Rounded
38
- borderColor?: string
39
- bgColor?: string
40
- separator?: Separator
41
- dense?: boolean
42
- fileRemoverIcon?: string
43
- fileSizeLimitKb?: number
44
- }>(),
45
- {
46
- modelValue: () => [],
47
- header: 'Upload Files',
48
- subHeader:
49
- 'Supports document uploads',
50
- fileType: '*',
51
- multiple: true,
52
- disabled: false,
53
- bordered: true,
54
- flat: false,
55
- rounded: 'xl',
56
- borderColor: 'gray-300',
57
- bgColor: 'white',
58
- separator: 'dashed',
59
- dense: false,
60
- fileRemoverIcon: 'delete',
61
- fileSizeLimitKb: 2048,
62
- },
63
- )
64
-
65
- const emit = defineEmits<{
66
- (
67
- e: 'update:modelValue',
68
- value: UploadedFile[],
69
- ): void
70
- }>()
71
-
72
- const fileInput =
73
- ref<HTMLInputElement | null>(
74
- null,
75
- )
76
-
77
- const errorMessage = ref('')
78
-
79
- const files = computed({
80
- get: () => props.modelValue,
81
-
82
- set: (
83
- value: UploadedFile[],
84
- ) =>
85
- emit(
86
- 'update:modelValue',
87
- value,
88
- ),
89
- })
90
-
91
- const isHex = (val: string) =>
92
- val.startsWith('#')
93
-
94
- const roundedClasses = computed(
95
- () => {
96
- const map = {
97
- none: '',
98
- sm: 'rounded-sm',
99
- md: 'rounded-md',
100
- lg: 'rounded-lg',
101
- xl: 'rounded-xl',
102
- }
103
-
104
- return map[props.rounded]
105
- },
106
- )
107
-
108
- const separatorClasses = computed(
109
- () => {
110
- switch (props.separator) {
111
- case 'solid':
112
- return 'border-solid'
113
-
114
- case 'dotted':
115
- return 'border-dotted'
116
-
117
- case 'dashed':
118
- default:
119
- return 'border-dashed'
120
- }
121
- },
122
- )
123
-
124
- const uploaderClasses = computed(
125
- () => [
126
- 'border-2 transition-all duration-300 flex flex-col items-center justify-center cursor-pointer',
127
-
128
- roundedClasses.value,
129
-
130
- separatorClasses.value,
131
-
132
- props.bordered
133
- ? !isHex(props.borderColor)
134
- ? `border-${props.borderColor}`
135
- : ''
136
- : 'border-transparent',
137
-
138
- props.flat
139
- ? 'shadow-none'
140
- : 'shadow-md',
141
-
142
- !isHex(props.bgColor)
143
- ? `bg-${props.bgColor}`
144
- : '',
145
-
146
- props.dense
147
- ? 'p-4'
148
- : 'p-8',
149
-
150
- props.disabled
151
- ? 'opacity-50 pointer-events-none'
152
- : 'hover:shadow-lg',
153
- ])
154
-
155
- const uploaderStyle = computed(
156
- () => {
157
- const style: Record<
158
- string,
159
- string
160
- > = {}
161
-
162
- if (isHex(props.borderColor)) {
163
- style.borderColor =
164
- props.borderColor
165
- }
166
-
167
- if (isHex(props.bgColor)) {
168
- style.backgroundColor =
169
- props.bgColor
170
- }
171
-
172
- return style
173
- },
174
- )
175
-
176
- const triggerFileInput =
177
- (): void => {
178
- fileInput.value?.click()
179
- }
180
-
181
- const createFileObject = (
182
- file: File,
183
- ): UploadedFile => ({
184
- file,
185
- name: file.name,
186
- size: file.size,
187
- type: file.type,
188
- })
189
-
190
- const handleFiles = (
191
- event: Event | DragEvent,
192
- ): void => {
193
- const selectedFiles =
194
- 'dataTransfer' in event &&
195
- event.dataTransfer
196
- ? Array.from(
197
- event.dataTransfer.files,
198
- )
199
- : Array.from(
200
- (
201
- event.target as HTMLInputElement
202
- ).files || [],
203
- )
204
-
205
- const validFiles =
206
- selectedFiles.filter((file) => {
207
- const fileSizeInKb =
208
- file.size / 1024
209
-
210
- if (
211
- fileSizeInKb >
212
- props.fileSizeLimitKb
213
- ) {
214
- errorMessage.value = `File "${file.name}" exceeds ${props.fileSizeLimitKb} KB`
215
-
216
- return false
217
- }
218
-
219
- return true
220
- })
221
-
222
- const mapped =
223
- validFiles.map(
224
- createFileObject,
225
- )
226
-
227
- files.value = props.multiple
228
- ? [
229
- ...files.value,
230
- ...mapped,
231
- ]
232
- : mapped
233
-
234
- if (mapped.length > 0) {
235
- errorMessage.value = ''
236
- }
237
- }
238
-
239
- const removeFile = (
240
- index: number,
241
- ): void => {
242
- files.value = files.value.filter(
243
- (_, i) => i !== index,
244
- )
245
- }
246
- </script>
247
-
248
- <template>
249
- <div class="max-w-lg mx-auto">
250
- <!-- Header -->
251
- <div class="mb-6 text-center">
252
- <h2 class="text-2xl font-bold text-gray-800 dark:text-white">
253
- {{ header }}
254
- </h2>
255
-
256
- <p class="text-sm text-gray-500">
257
- {{ subHeader }}
258
- </p>
259
- </div>
260
-
261
- <!-- Hidden Input -->
262
- <input ref="fileInput" type="file" class="hidden" :accept="fileType" :multiple="multiple" @change="handleFiles">
263
-
264
- <!-- Dropzone -->
265
- <div :class="uploaderClasses" :style="uploaderStyle" @click="triggerFileInput" @dragover.prevent @drop.prevent="
266
- handleFiles($event)
267
- ">
268
- <slot name="content">
269
- <p class="text-gray-600 mb-4">
270
- {{
271
- multiple
272
- ? 'Drag & drop files here'
273
- : 'Drag & drop file here'
274
- }}
275
- </p>
276
-
277
- <button type="button" class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
278
- {{
279
- multiple
280
- ? 'Browse Files'
281
- : 'Browse File'
282
- }}
283
- </button>
284
- </slot>
285
- </div>
286
-
287
- <!-- Uploaded Files -->
288
- <div v-if="files.length" class="mt-6">
289
- <h3 class="text-lg font-semibold mb-4">
290
- Uploaded Files
291
- </h3>
292
-
293
- <ul class="space-y-2">
294
- <li v-for="(file, index) in files" :key="index"
295
- class="flex items-center justify-between p-4 rounded-lg border border-gray-200 bg-gray-50">
296
- <div class="flex items-center gap-3">
297
- <span class="material-icons text-blue-500">
298
- description
299
- </span>
300
-
301
- <span>
302
- {{ file.name }}
303
- </span>
304
- </div>
305
-
306
- <button type="button" class="text-red-500 hover:text-red-700" @click.stop="
307
- removeFile(index)
308
- ">
309
- <span class="material-icons">
310
- {{
311
- fileRemoverIcon
312
- }}
313
- </span>
314
- </button>
315
- </li>
316
- </ul>
317
- </div>
318
-
319
- <!-- Error -->
320
- <div v-if="errorMessage" class="mt-4 text-sm text-red-500">
321
- {{ errorMessage }}
322
- </div>
323
- </div>
324
- </template>
325
-
326
- <style scoped>
327
- .material-icons {
328
- font-size: 20px;
329
- }
330
- </style>
@@ -1,82 +0,0 @@
1
- <script setup lang="ts">
2
- defineOptions({
3
- inheritAttrs: false,
4
- })
5
-
6
- import { computed } from 'vue'
7
-
8
- const props = defineProps({
9
- name: { type: String, required: true },
10
-
11
- library: {
12
- type: String,
13
- default: 'material',
14
- },
15
-
16
- color: {
17
- type: String,
18
- default: '',
19
- },
20
-
21
- size: {
22
- type: String,
23
- default: 'md',
24
- },
25
- })
26
-
27
- const isHex = (val: string) => val.startsWith('#')
28
-
29
- const sizeMap = {
30
- xs: 'text-xs',
31
- sm: 'text-sm',
32
- md: 'text-base',
33
- lg: 'text-xl',
34
- xl: 'text-3xl',
35
- }
36
-
37
- const iconStyle = computed(() => {
38
- const style: Record<string, string> = {}
39
-
40
- if (isHex(props.color)) {
41
- style.color = props.color
42
- }
43
-
44
- return style
45
- })
46
-
47
- const iconClass = computed(() => {
48
- const classes = [
49
- sizeMap[props.size as keyof typeof sizeMap],
50
- ]
51
-
52
- if (!isHex(props.color) && props.color) {
53
- classes.push(`text-${props.color}`)
54
- }
55
-
56
- switch (props.library) {
57
- case 'material':
58
- classes.push('material-icons')
59
- break
60
-
61
- case 'material-symbols':
62
- classes.push('material-symbols-outlined')
63
- break
64
-
65
- case 'fontawesome':
66
- classes.push(props.name)
67
- break
68
- }
69
-
70
- return classes
71
- })
72
- </script>
73
-
74
- <template>
75
- <i
76
- :class="iconClass"
77
- :style="iconStyle"
78
- v-bind="$attrs"
79
- >
80
- {{ library.includes('material') ? name : '' }}
81
- </i>
82
- </template>