windly-ui 1.0.1 → 1.0.2

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 (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -33
  3. package/package.json +47 -15
  4. package/ui-library/dist/module.d.mts +3 -0
  5. package/ui-library/dist/module.json +8 -0
  6. package/ui-library/dist/module.mjs +22 -0
  7. package/ui-library/dist/types.d.mts +7 -0
  8. package/ui-library/components/Accordion.vue +0 -118
  9. package/ui-library/components/Avatar.vue +0 -121
  10. package/ui-library/components/Badge.vue +0 -116
  11. package/ui-library/components/Breadcrumbs.vue +0 -138
  12. package/ui-library/components/Button.vue +0 -154
  13. package/ui-library/components/Card.vue +0 -84
  14. package/ui-library/components/Checkbox.vue +0 -148
  15. package/ui-library/components/CodeBlock.vue +0 -99
  16. package/ui-library/components/ColorPicker.vue +0 -302
  17. package/ui-library/components/Date.vue +0 -240
  18. package/ui-library/components/Dialog.vue +0 -187
  19. package/ui-library/components/Divider.vue +0 -78
  20. package/ui-library/components/Drawer.vue +0 -67
  21. package/ui-library/components/Dropdown.vue +0 -248
  22. package/ui-library/components/FileUploader.vue +0 -330
  23. package/ui-library/components/Icon.vue +0 -82
  24. package/ui-library/components/Image.vue +0 -78
  25. package/ui-library/components/Input.vue +0 -531
  26. package/ui-library/components/Radio.vue +0 -356
  27. package/ui-library/components/ScrollArea.vue +0 -43
  28. package/ui-library/components/Select.vue +0 -309
  29. package/ui-library/components/Stepper.vue +0 -361
  30. package/ui-library/components/TabPanel.vue +0 -25
  31. package/ui-library/components/Table.vue +0 -152
  32. package/ui-library/components/Tabs.vue +0 -71
  33. package/ui-library/components/Textarea.vue +0 -233
  34. package/ui-library/components/Toggle.vue +0 -319
  35. package/ui-library/components/Tooltip.vue +0 -200
  36. package/ui-library/components/plugin.ts +0 -8
  37. package/ui-library/components/uiProps.ts +0 -11
  38. package/ui-library/components/useUiClasses.ts +0 -159
  39. package/ui-library/module.ts +0 -20
@@ -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>
@@ -1,78 +0,0 @@
1
- <script setup lang="ts">
2
- defineOptions({
3
- inheritAttrs: false,
4
- })
5
-
6
- import { computed, ref } from 'vue'
7
-
8
- const props = defineProps({
9
- src: { type: String, required: true },
10
-
11
- alt: { type: String, default: '' },
12
-
13
- placeholder: {
14
- type: String,
15
- default: '/images/placeholder.png'
16
- },
17
-
18
- width: { type: String, default: '100%' },
19
- height: { type: String, default: 'auto' },
20
-
21
- fit: {
22
- type: String,
23
- default: 'cover',
24
- },
25
-
26
- borderColor: {
27
- type: String,
28
- default: '',
29
- },
30
-
31
- borderType: {
32
- type: String,
33
- default: 'none',
34
- },
35
- })
36
-
37
- const imageSrc = ref(props.src)
38
-
39
- const isHex = (val: string) => val.startsWith('#')
40
-
41
- const imageStyle = computed(() => {
42
- const style: Record<string, string> = {
43
- width: props.width,
44
- height: props.height,
45
- objectFit: props.fit,
46
- }
47
-
48
- if (isHex(props.borderColor)) {
49
- style.borderColor = props.borderColor
50
- }
51
-
52
- return style
53
- })
54
-
55
- const imageClass = computed(() => [
56
- props.borderType !== 'none' ? 'border' : '',
57
- props.borderType === 'dashed' ? 'border-dashed' : '',
58
- props.borderType === 'dotted' ? 'border-dotted' : '',
59
- !isHex(props.borderColor)
60
- ? `border-${props.borderColor}`
61
- : '',
62
- ])
63
-
64
- function onError() {
65
- imageSrc.value = props.placeholder
66
- }
67
- </script>
68
-
69
- <template>
70
- <img
71
- :src="imageSrc"
72
- :alt="alt"
73
- :class="imageClass"
74
- :style="imageStyle"
75
- @error="onError"
76
- v-bind="$attrs"
77
- >
78
- </template>