@baklavue/ui 1.0.0-preview.4 → 1.0.1

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 (287) hide show
  1. package/dist/accordion/Accordion.vue.d.ts +51 -0
  2. package/dist/accordion/Accordion.vue.d.ts.map +1 -0
  3. package/dist/accordion/accordion.types.d.ts +97 -0
  4. package/dist/accordion/accordion.types.d.ts.map +1 -0
  5. package/dist/accordion/index.d.ts +3 -0
  6. package/dist/accordion/index.d.ts.map +1 -0
  7. package/dist/alert/Alert.vue.d.ts +49 -0
  8. package/dist/alert/Alert.vue.d.ts.map +1 -0
  9. package/dist/alert/alert.types.d.ts +52 -0
  10. package/dist/alert/alert.types.d.ts.map +1 -0
  11. package/dist/alert/index.d.ts +3 -0
  12. package/dist/alert/index.d.ts.map +1 -0
  13. package/dist/badge/Badge.vue.d.ts +22 -0
  14. package/dist/badge/Badge.vue.d.ts.map +1 -0
  15. package/dist/badge/badge.types.d.ts +7 -0
  16. package/dist/badge/badge.types.d.ts.map +1 -0
  17. package/dist/badge/index.d.ts +3 -0
  18. package/dist/badge/index.d.ts.map +1 -0
  19. package/dist/banner/Banner.vue.d.ts +36 -0
  20. package/dist/banner/Banner.vue.d.ts.map +1 -0
  21. package/dist/banner/banner.types.d.ts +70 -0
  22. package/dist/banner/banner.types.d.ts.map +1 -0
  23. package/dist/banner/index.d.ts +3 -0
  24. package/dist/banner/index.d.ts.map +1 -0
  25. package/dist/button/Button.vue.d.ts +36 -0
  26. package/dist/button/Button.vue.d.ts.map +1 -0
  27. package/dist/button/button.types.d.ts +24 -0
  28. package/dist/button/button.types.d.ts.map +1 -0
  29. package/dist/button/index.d.ts +3 -0
  30. package/dist/button/index.d.ts.map +1 -0
  31. package/dist/checkbox/Checkbox.vue.d.ts +39 -0
  32. package/dist/checkbox/Checkbox.vue.d.ts.map +1 -0
  33. package/dist/checkbox/checkbox.types.d.ts +95 -0
  34. package/dist/checkbox/checkbox.types.d.ts.map +1 -0
  35. package/dist/checkbox/index.d.ts +3 -0
  36. package/dist/checkbox/index.d.ts.map +1 -0
  37. package/dist/chip/Chip.vue.d.ts +29 -0
  38. package/dist/chip/Chip.vue.d.ts.map +1 -0
  39. package/dist/chip/chip.types.d.ts +59 -0
  40. package/dist/chip/chip.types.d.ts.map +1 -0
  41. package/dist/chip/index.d.ts +3 -0
  42. package/dist/chip/index.d.ts.map +1 -0
  43. package/dist/datepicker/Datepicker.vue.d.ts +41 -0
  44. package/dist/datepicker/Datepicker.vue.d.ts.map +1 -0
  45. package/dist/datepicker/datepicker.types.d.ts +38 -0
  46. package/dist/datepicker/datepicker.types.d.ts.map +1 -0
  47. package/dist/datepicker/index.d.ts +3 -0
  48. package/dist/datepicker/index.d.ts.map +1 -0
  49. package/dist/dialog/Dialog.vue.d.ts +44 -0
  50. package/dist/dialog/Dialog.vue.d.ts.map +1 -0
  51. package/dist/dialog/dialog.types.d.ts +18 -0
  52. package/dist/dialog/dialog.types.d.ts.map +1 -0
  53. package/dist/dialog/index.d.ts +3 -0
  54. package/dist/dialog/index.d.ts.map +1 -0
  55. package/dist/drawer/Drawer.vue.d.ts +42 -0
  56. package/dist/drawer/Drawer.vue.d.ts.map +1 -0
  57. package/dist/drawer/drawer.types.d.ts +18 -0
  58. package/dist/drawer/drawer.types.d.ts.map +1 -0
  59. package/dist/drawer/index.d.ts +3 -0
  60. package/dist/drawer/index.d.ts.map +1 -0
  61. package/dist/dropdown/Dropdown.vue.d.ts +59 -0
  62. package/dist/dropdown/Dropdown.vue.d.ts.map +1 -0
  63. package/dist/dropdown/dropdown.types.d.ts +92 -0
  64. package/dist/dropdown/dropdown.types.d.ts.map +1 -0
  65. package/dist/dropdown/index.d.ts +3 -0
  66. package/dist/dropdown/index.d.ts.map +1 -0
  67. package/dist/file-upload/FileUpload.vue.d.ts +44 -0
  68. package/dist/file-upload/FileUpload.vue.d.ts.map +1 -0
  69. package/dist/file-upload/file-upload.types.d.ts +76 -0
  70. package/dist/file-upload/file-upload.types.d.ts.map +1 -0
  71. package/dist/file-upload/index.d.ts +3 -0
  72. package/dist/file-upload/index.d.ts.map +1 -0
  73. package/dist/icon/Icon.vue.d.ts +29 -0
  74. package/dist/icon/Icon.vue.d.ts.map +1 -0
  75. package/dist/icon/icon.types.d.ts +23 -0
  76. package/dist/icon/icon.types.d.ts.map +1 -0
  77. package/dist/icon/index.d.ts +3 -0
  78. package/dist/icon/index.d.ts.map +1 -0
  79. package/dist/image/Image.vue.d.ts +30 -0
  80. package/dist/image/Image.vue.d.ts.map +1 -0
  81. package/dist/image/image.types.d.ts +48 -0
  82. package/dist/image/image.types.d.ts.map +1 -0
  83. package/dist/image/index.d.ts +3 -0
  84. package/dist/image/index.d.ts.map +1 -0
  85. package/dist/index.css +474 -0
  86. package/dist/index.d.ts +42 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +2404 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/input/Input.vue.d.ts +39 -0
  91. package/dist/input/Input.vue.d.ts.map +1 -0
  92. package/dist/input/index.d.ts +3 -0
  93. package/dist/input/index.d.ts.map +1 -0
  94. package/dist/input/input.types.d.ts +122 -0
  95. package/dist/input/input.types.d.ts.map +1 -0
  96. package/dist/link/Link.vue.d.ts +38 -0
  97. package/dist/link/Link.vue.d.ts.map +1 -0
  98. package/dist/link/index.d.ts +3 -0
  99. package/dist/link/index.d.ts.map +1 -0
  100. package/dist/link/link.types.d.ts +40 -0
  101. package/dist/link/link.types.d.ts.map +1 -0
  102. package/dist/notification/Notification.vue.d.ts +7 -0
  103. package/dist/notification/Notification.vue.d.ts.map +1 -0
  104. package/dist/notification/index.d.ts +3 -0
  105. package/dist/notification/index.d.ts.map +1 -0
  106. package/dist/notification/notification.types.d.ts +25 -0
  107. package/dist/notification/notification.types.d.ts.map +1 -0
  108. package/dist/pagination/Pagination.vue.d.ts +34 -0
  109. package/dist/pagination/Pagination.vue.d.ts.map +1 -0
  110. package/dist/pagination/index.d.ts +3 -0
  111. package/dist/pagination/index.d.ts.map +1 -0
  112. package/dist/pagination/pagination.types.d.ts +54 -0
  113. package/dist/pagination/pagination.types.d.ts.map +1 -0
  114. package/dist/radio/Radio.vue.d.ts +42 -0
  115. package/dist/radio/Radio.vue.d.ts.map +1 -0
  116. package/dist/radio/index.d.ts +3 -0
  117. package/dist/radio/index.d.ts.map +1 -0
  118. package/dist/radio/radio.types.d.ts +84 -0
  119. package/dist/radio/radio.types.d.ts.map +1 -0
  120. package/dist/scroll-to-top/ScrollToTop.vue.d.ts +14 -0
  121. package/dist/scroll-to-top/ScrollToTop.vue.d.ts.map +1 -0
  122. package/dist/scroll-to-top/index.d.ts +3 -0
  123. package/dist/scroll-to-top/index.d.ts.map +1 -0
  124. package/dist/scroll-to-top/scroll-to-top.types.d.ts +33 -0
  125. package/dist/scroll-to-top/scroll-to-top.types.d.ts.map +1 -0
  126. package/dist/select/Select.vue.d.ts +42 -0
  127. package/dist/select/Select.vue.d.ts.map +1 -0
  128. package/dist/select/index.d.ts +3 -0
  129. package/dist/select/index.d.ts.map +1 -0
  130. package/dist/select/select.types.d.ts +52 -0
  131. package/dist/select/select.types.d.ts.map +1 -0
  132. package/dist/skeleton/Skeleton.vue.d.ts +9 -0
  133. package/dist/skeleton/Skeleton.vue.d.ts.map +1 -0
  134. package/dist/skeleton/index.d.ts +3 -0
  135. package/dist/skeleton/index.d.ts.map +1 -0
  136. package/dist/skeleton/skeleton.types.d.ts +30 -0
  137. package/dist/skeleton/skeleton.types.d.ts.map +1 -0
  138. package/dist/spinner/Spinner.vue.d.ts +8 -0
  139. package/dist/spinner/Spinner.vue.d.ts.map +1 -0
  140. package/dist/spinner/index.d.ts +3 -0
  141. package/dist/spinner/index.d.ts.map +1 -0
  142. package/dist/spinner/spinner.types.d.ts +12 -0
  143. package/dist/spinner/spinner.types.d.ts.map +1 -0
  144. package/dist/split-button/SplitButton.vue.d.ts +25 -0
  145. package/dist/split-button/SplitButton.vue.d.ts.map +1 -0
  146. package/dist/split-button/index.d.ts +3 -0
  147. package/dist/split-button/index.d.ts.map +1 -0
  148. package/dist/split-button/split-button.types.d.ts +19 -0
  149. package/dist/split-button/split-button.types.d.ts.map +1 -0
  150. package/dist/stepper/Stepper.vue.d.ts +30 -0
  151. package/dist/stepper/Stepper.vue.d.ts.map +1 -0
  152. package/dist/stepper/index.d.ts +3 -0
  153. package/dist/stepper/index.d.ts.map +1 -0
  154. package/dist/stepper/stepper.types.d.ts +29 -0
  155. package/dist/stepper/stepper.types.d.ts.map +1 -0
  156. package/dist/switch/Switch.vue.d.ts +32 -0
  157. package/dist/switch/Switch.vue.d.ts.map +1 -0
  158. package/dist/switch/index.d.ts +3 -0
  159. package/dist/switch/index.d.ts.map +1 -0
  160. package/dist/switch/switch.types.d.ts +14 -0
  161. package/dist/switch/switch.types.d.ts.map +1 -0
  162. package/dist/tab/Tab.vue.d.ts +31 -0
  163. package/dist/tab/Tab.vue.d.ts.map +1 -0
  164. package/dist/tab/index.d.ts +3 -0
  165. package/dist/tab/index.d.ts.map +1 -0
  166. package/dist/tab/tab.types.d.ts +17 -0
  167. package/dist/tab/tab.types.d.ts.map +1 -0
  168. package/dist/table/Table.vue.d.ts +181 -0
  169. package/dist/table/Table.vue.d.ts.map +1 -0
  170. package/dist/table/index.d.ts +3 -0
  171. package/dist/table/index.d.ts.map +1 -0
  172. package/dist/table/table.types.d.ts +61 -0
  173. package/dist/table/table.types.d.ts.map +1 -0
  174. package/dist/tag/Tag.vue.d.ts +31 -0
  175. package/dist/tag/Tag.vue.d.ts.map +1 -0
  176. package/dist/tag/index.d.ts +3 -0
  177. package/dist/tag/index.d.ts.map +1 -0
  178. package/dist/tag/tag.types.d.ts +22 -0
  179. package/dist/tag/tag.types.d.ts.map +1 -0
  180. package/dist/textarea/Textarea.vue.d.ts +35 -0
  181. package/dist/textarea/Textarea.vue.d.ts.map +1 -0
  182. package/dist/textarea/index.d.ts +3 -0
  183. package/dist/textarea/index.d.ts.map +1 -0
  184. package/dist/textarea/textarea.types.d.ts +37 -0
  185. package/dist/textarea/textarea.types.d.ts.map +1 -0
  186. package/dist/tooltip/Tooltip.vue.d.ts +33 -0
  187. package/dist/tooltip/Tooltip.vue.d.ts.map +1 -0
  188. package/dist/tooltip/index.d.ts +3 -0
  189. package/dist/tooltip/index.d.ts.map +1 -0
  190. package/dist/tooltip/tooltip.types.d.ts +17 -0
  191. package/dist/tooltip/tooltip.types.d.ts.map +1 -0
  192. package/dist/utils/loadBaklavaResources.d.ts +2 -0
  193. package/dist/utils/loadBaklavaResources.d.ts.map +1 -0
  194. package/package.json +28 -4
  195. package/.releaserc.json +0 -14
  196. package/CHANGELOG.md +0 -56
  197. package/index.ts +0 -1
  198. package/src/accordion/Accordion.vue +0 -206
  199. package/src/accordion/accordion.types.ts +0 -109
  200. package/src/accordion/index.ts +0 -3
  201. package/src/alert/Alert.vue +0 -199
  202. package/src/alert/alert.types.ts +0 -58
  203. package/src/alert/index.ts +0 -2
  204. package/src/badge/Badge.vue +0 -20
  205. package/src/badge/badge.types.ts +0 -7
  206. package/src/badge/index.ts +0 -2
  207. package/src/button/Button.vue +0 -45
  208. package/src/button/button.types.ts +0 -30
  209. package/src/button/index.ts +0 -3
  210. package/src/checkbox/Checkbox.vue +0 -148
  211. package/src/checkbox/checkbox.types.ts +0 -108
  212. package/src/checkbox/index.ts +0 -2
  213. package/src/datepicker/Datepicker.vue +0 -172
  214. package/src/datepicker/datepicker.types.ts +0 -39
  215. package/src/datepicker/index.ts +0 -2
  216. package/src/dialog/Dialog.vue +0 -178
  217. package/src/dialog/dialog.types.ts +0 -17
  218. package/src/dialog/index.ts +0 -2
  219. package/src/drawer/Drawer.vue +0 -162
  220. package/src/drawer/drawer.types.ts +0 -17
  221. package/src/drawer/index.ts +0 -2
  222. package/src/dropdown/Dropdown.vue +0 -231
  223. package/src/dropdown/dropdown.types.ts +0 -110
  224. package/src/dropdown/index.ts +0 -2
  225. package/src/file-upload/FileUpload.vue +0 -440
  226. package/src/file-upload/file-upload.types.ts +0 -89
  227. package/src/file-upload/index.ts +0 -7
  228. package/src/icon/Icon.vue +0 -102
  229. package/src/icon/icon.types.ts +0 -25
  230. package/src/icon/index.ts +0 -2
  231. package/src/image/Image.vue +0 -144
  232. package/src/image/image.types.ts +0 -57
  233. package/src/image/index.ts +0 -3
  234. package/src/index.ts +0 -41
  235. package/src/input/Input.vue +0 -148
  236. package/src/input/index.ts +0 -3
  237. package/src/input/input.types.ts +0 -156
  238. package/src/link/Link.vue +0 -133
  239. package/src/link/index.ts +0 -2
  240. package/src/link/link.types.ts +0 -42
  241. package/src/notification/Notification.vue +0 -57
  242. package/src/notification/index.ts +0 -2
  243. package/src/notification/notification.types.ts +0 -25
  244. package/src/pagination/Pagination.vue +0 -137
  245. package/src/pagination/index.ts +0 -2
  246. package/src/pagination/pagination.types.ts +0 -61
  247. package/src/radio/Radio.vue +0 -205
  248. package/src/radio/index.ts +0 -2
  249. package/src/radio/radio.types.ts +0 -95
  250. package/src/scroll-to-top/ScrollToTop.vue +0 -130
  251. package/src/scroll-to-top/index.ts +0 -2
  252. package/src/scroll-to-top/scroll-to-top.types.ts +0 -42
  253. package/src/select/Select.vue +0 -147
  254. package/src/select/index.ts +0 -2
  255. package/src/select/select.types.ts +0 -53
  256. package/src/skeleton/Skeleton.vue +0 -115
  257. package/src/skeleton/index.ts +0 -2
  258. package/src/skeleton/skeleton.types.ts +0 -33
  259. package/src/spinner/Spinner.vue +0 -49
  260. package/src/spinner/index.ts +0 -2
  261. package/src/spinner/spinner.types.ts +0 -11
  262. package/src/split-button/SplitButton.vue +0 -73
  263. package/src/split-button/index.ts +0 -2
  264. package/src/split-button/split-button.types.ts +0 -19
  265. package/src/stepper/Stepper.vue +0 -100
  266. package/src/stepper/index.ts +0 -2
  267. package/src/stepper/stepper.types.ts +0 -29
  268. package/src/switch/Switch.vue +0 -80
  269. package/src/switch/index.ts +0 -2
  270. package/src/switch/switch.types.ts +0 -13
  271. package/src/tab/Tab.vue +0 -99
  272. package/src/tab/index.ts +0 -2
  273. package/src/tab/tab.types.ts +0 -17
  274. package/src/table/Table.vue +0 -264
  275. package/src/table/index.ts +0 -7
  276. package/src/table/table.types.ts +0 -62
  277. package/src/tag/Tag.vue +0 -83
  278. package/src/tag/index.ts +0 -2
  279. package/src/tag/tag.types.ts +0 -24
  280. package/src/textarea/Textarea.vue +0 -84
  281. package/src/textarea/index.ts +0 -2
  282. package/src/textarea/textarea.types.ts +0 -37
  283. package/src/tooltip/Tooltip.vue +0 -81
  284. package/src/tooltip/index.ts +0 -3
  285. package/src/tooltip/tooltip.types.ts +0 -29
  286. package/src/utils/loadBaklavaResources.ts +0 -24
  287. package/tsconfig.json +0 -28
@@ -1,440 +0,0 @@
1
- <script setup lang="ts">
2
- /**
3
- * FileUpload Component
4
- *
5
- * A custom file upload component with drag-and-drop zone, click-to-browse,
6
- * file list with remove, validation (size/type), and optional preview.
7
- *
8
- * @component
9
- * @example
10
- * ```vue
11
- * <!-- Basic usage -->
12
- * <template>
13
- * <BvFileUpload v-model="file" label="Upload document" />
14
- * </template>
15
- * ```
16
- *
17
- * @example
18
- * ```vue
19
- * <!-- Multiple with validation -->
20
- * <template>
21
- * <BvFileUpload
22
- * v-model="files"
23
- * multiple
24
- * accept="image/*"
25
- * :max-size="1024 * 1024"
26
- * @invalid="handleInvalid"
27
- * />
28
- * </template>
29
- * ```
30
- */
31
- import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
32
- import BvIcon from "../icon/Icon.vue";
33
- import BvTag from "../tag/Tag.vue";
34
- import { loadBaklavaResources } from "../utils/loadBaklavaResources";
35
- import type {
36
- FileUploadInvalidEntry,
37
- FileUploadProps,
38
- } from "./file-upload.types";
39
-
40
- const props = withDefaults(defineProps<FileUploadProps>(), {
41
- modelValue: undefined,
42
- multiple: false,
43
- accept: undefined,
44
- maxSize: undefined,
45
- minSize: undefined,
46
- maxFiles: undefined,
47
- disabled: false,
48
- label: undefined,
49
- helpText: undefined,
50
- invalidText: undefined,
51
- showPreview: false,
52
- size: "medium",
53
- });
54
-
55
- const emit = defineEmits<{
56
- "update:modelValue": [value: File | File[] | null];
57
- invalid: [entries: FileUploadInvalidEntry[]];
58
- change: [files: File[]];
59
- }>();
60
-
61
- const inputRef = ref<HTMLInputElement | null>(null);
62
- const isDragging = ref(false);
63
- const previewUrls = ref<Map<File, string>>(new Map());
64
-
65
- /** Normalize modelValue to File[] */
66
- const filesList = computed<File[]>(() => {
67
- const v = props.modelValue;
68
- if (!v) return [];
69
- return Array.isArray(v) ? [...v] : [v];
70
- });
71
-
72
- /** Check if file passes accept filter */
73
- function matchesAccept(file: File): boolean {
74
- if (!props.accept) return true;
75
- const rules = props.accept.split(",").map((r) => r.trim());
76
- const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
77
-
78
- for (const rule of rules) {
79
- if (rule.startsWith(".")) {
80
- if (ext === rule.slice(1).toLowerCase()) return true;
81
- } else {
82
- const mime = file.type;
83
- if (rule.endsWith("/*")) {
84
- const base = rule.slice(0, -1);
85
- if (mime.startsWith(base)) return true;
86
- } else if (mime === rule) {
87
- return true;
88
- }
89
- }
90
- }
91
- return false;
92
- }
93
-
94
- /** Validate files and return invalid entries */
95
- function validateFiles(
96
- incoming: File[],
97
- existingCount: number,
98
- ): FileUploadInvalidEntry[] {
99
- const invalid: FileUploadInvalidEntry[] = [];
100
- const maxFiles = props.maxFiles ?? Infinity;
101
- let validAdded = 0;
102
-
103
- for (const file of incoming) {
104
- if (!matchesAccept(file)) {
105
- invalid.push({ file, reason: "type" });
106
- continue;
107
- }
108
- if (props.maxSize !== undefined && file.size > props.maxSize) {
109
- invalid.push({ file, reason: "size" });
110
- continue;
111
- }
112
- if (props.minSize !== undefined && file.size < props.minSize) {
113
- invalid.push({ file, reason: "size" });
114
- continue;
115
- }
116
- if (props.multiple && existingCount + validAdded >= maxFiles) {
117
- invalid.push({ file, reason: "count" });
118
- continue;
119
- }
120
- validAdded++;
121
- }
122
-
123
- return invalid;
124
- }
125
-
126
- /** Process and emit validated files */
127
- function processFiles(newFiles: File[]) {
128
- const valid: File[] = [];
129
- const invalid = validateFiles(newFiles, filesList.value.length);
130
-
131
- for (const f of newFiles) {
132
- const entry = invalid.find((e) => e.file === f);
133
- if (!entry) valid.push(f);
134
- }
135
-
136
- if (invalid.length > 0) {
137
- emit("invalid", invalid);
138
- }
139
-
140
- if (valid.length > 0) {
141
- const combined = props.multiple
142
- ? [...filesList.value, ...valid]
143
- : [valid[0]];
144
- const out = props.multiple ? combined : combined[0];
145
- emit("update:modelValue", out);
146
- emit("change", combined);
147
- }
148
- }
149
-
150
- function handleInputChange(e: Event) {
151
- const input = e.target as HTMLInputElement;
152
- const files = input.files ? Array.from(input.files) : [];
153
- processFiles(files);
154
- input.value = "";
155
- }
156
-
157
- function handleDrop(e: DragEvent) {
158
- e.preventDefault();
159
- isDragging.value = false;
160
- if (props.disabled) return;
161
- const files = e.dataTransfer?.files ? Array.from(e.dataTransfer.files) : [];
162
- processFiles(files);
163
- }
164
-
165
- function handleDragOver(e: DragEvent) {
166
- e.preventDefault();
167
- e.stopPropagation();
168
- if (props.disabled) return;
169
- isDragging.value = true;
170
- }
171
-
172
- function handleDragLeave() {
173
- isDragging.value = false;
174
- }
175
-
176
- function openFilePicker() {
177
- if (props.disabled) return;
178
- inputRef.value?.click();
179
- }
180
-
181
- function removeFile(index: number) {
182
- const list = [...filesList.value];
183
- const removed = list[index];
184
- list.splice(index, 1);
185
- if (props.showPreview && removed && removed.type.startsWith("image/")) {
186
- const url = previewUrls.value.get(removed);
187
- if (url) URL.revokeObjectURL(url);
188
- previewUrls.value.delete(removed);
189
- }
190
- const out = props.multiple ? list : (list[0] ?? null);
191
- emit("update:modelValue", out);
192
- emit("change", list);
193
- }
194
-
195
- function getPreviewUrl(file: File): string {
196
- if (!file.type.startsWith("image/")) return "";
197
- let url = previewUrls.value.get(file);
198
- if (!url) {
199
- url = URL.createObjectURL(file);
200
- previewUrls.value.set(file, url);
201
- }
202
- return url;
203
- }
204
-
205
- watch(
206
- filesList,
207
- (files) => {
208
- const toRevoke = new Set(previewUrls.value.keys());
209
- for (const f of files) {
210
- toRevoke.delete(f);
211
- }
212
- for (const f of toRevoke) {
213
- const url = previewUrls.value.get(f);
214
- if (url) URL.revokeObjectURL(url);
215
- previewUrls.value.delete(f);
216
- }
217
- },
218
- { deep: true },
219
- );
220
-
221
- onMounted(() => {
222
- loadBaklavaResources();
223
- });
224
-
225
- onBeforeUnmount(() => {
226
- for (const url of previewUrls.value.values()) {
227
- URL.revokeObjectURL(url);
228
- }
229
- previewUrls.value.clear();
230
- });
231
-
232
- const zoneSizeClass = computed(() => `file-upload-zone--${props.size}`);
233
- const hasError = computed(() => !!props.invalidText);
234
- </script>
235
-
236
- <template>
237
- <div class="file-upload">
238
- <label v-if="label" class="file-upload-label">{{ label }}</label>
239
-
240
- <div
241
- class="file-upload-zone"
242
- :class="[
243
- zoneSizeClass,
244
- {
245
- 'file-upload-zone--dragging': isDragging,
246
- 'file-upload-zone--disabled': disabled,
247
- 'file-upload-zone--invalid': hasError,
248
- },
249
- ]"
250
- @click="openFilePicker"
251
- @drop="handleDrop"
252
- @dragover="handleDragOver"
253
- @dragleave="handleDragLeave"
254
- >
255
- <input
256
- ref="inputRef"
257
- type="file"
258
- class="file-upload-input"
259
- :accept="accept"
260
- :multiple="multiple"
261
- :disabled="disabled"
262
- @change="handleInputChange"
263
- />
264
- <div class="file-upload-content">
265
- <BvIcon name="upload" size="24px" class="file-upload-icon" />
266
- <span class="file-upload-text">
267
- <slot name="hint"> </slot>
268
- </span>
269
- </div>
270
- </div>
271
-
272
- <p v-if="helpText && !hasError" class="file-upload-help">{{ helpText }}</p>
273
- <p v-if="invalidText" class="file-upload-invalid">{{ invalidText }}</p>
274
-
275
- <div v-if="filesList.length > 0" class="file-upload-list">
276
- <div
277
- v-for="(file, index) in filesList"
278
- :key="`${file.name}-${file.size}-${index}`"
279
- class="file-upload-item"
280
- >
281
- <div
282
- v-if="showPreview && file.type.startsWith('image/')"
283
- class="file-upload-preview"
284
- >
285
- <img
286
- :src="getPreviewUrl(file)"
287
- :alt="file.name"
288
- class="file-upload-thumb"
289
- />
290
- </div>
291
- <BvTag
292
- closable
293
- size="small"
294
- class="file-upload-tag"
295
- @close="removeFile(index)"
296
- >
297
- {{ file.name }} ({{ (file.size / 1024).toFixed(1) }} KB)
298
- </BvTag>
299
- </div>
300
- </div>
301
- </div>
302
- </template>
303
-
304
- <style scoped>
305
- .file-upload {
306
- display: flex;
307
- flex-direction: column;
308
- gap: var(--bl-spacing-2, 0.5rem);
309
- }
310
-
311
- .file-upload-label {
312
- font: var(--bl-font-body-2-medium, 0.875rem 500);
313
- color: var(--bl-color-neutral-darker, #374151);
314
- }
315
-
316
- .file-upload-zone {
317
- display: flex;
318
- align-items: center;
319
- justify-content: center;
320
- border: 2px dashed var(--bl-color-neutral-light, #e5e7eb);
321
- border-radius: var(--bl-radius-m, 8px);
322
- background: var(--bl-color-neutral-background, #f9fafb);
323
- cursor: pointer;
324
- transition:
325
- border-color 0.2s,
326
- background 0.2s;
327
- }
328
-
329
- .file-upload-zone:hover:not(.file-upload-zone--disabled) {
330
- border-color: var(--bl-color-primary, #ff6000);
331
- background: var(--bl-color-primary-background, #fff5f0);
332
- }
333
-
334
- .file-upload-zone--dragging {
335
- border-color: var(--bl-color-primary, #ff6000);
336
- background: var(--bl-color-primary-background, #fff5f0);
337
- }
338
-
339
- .file-upload-zone--disabled {
340
- cursor: not-allowed;
341
- opacity: 0.6;
342
- }
343
-
344
- .file-upload-zone--invalid {
345
- border-color: var(--bl-color-danger, #dc2626);
346
- }
347
-
348
- .file-upload-zone--small {
349
- min-height: 80px;
350
- padding: var(--bl-spacing-3, 0.75rem);
351
- }
352
-
353
- .file-upload-zone--medium {
354
- min-height: 120px;
355
- padding: var(--bl-spacing-4, 1rem);
356
- }
357
-
358
- .file-upload-zone--large {
359
- min-height: 160px;
360
- padding: var(--bl-spacing-5, 1.25rem);
361
- }
362
-
363
- .file-upload-input {
364
- position: absolute;
365
- width: 0;
366
- height: 0;
367
- opacity: 0;
368
- overflow: hidden;
369
- pointer-events: none;
370
- }
371
-
372
- .file-upload-content {
373
- display: flex;
374
- flex-direction: column;
375
- align-items: center;
376
- gap: var(--bl-spacing-2, 0.5rem);
377
- }
378
-
379
- .file-upload-icon {
380
- color: var(--bl-color-neutral-subtle, #9ca3af);
381
- }
382
-
383
- .file-upload-text {
384
- font: var(--bl-font-body-2-regular, 0.875rem 400);
385
- color: var(--bl-color-neutral-subtle, #6b7280);
386
- }
387
-
388
- .file-upload-browse {
389
- color: var(--bl-color-primary, #ff6000);
390
- text-decoration: underline;
391
- }
392
-
393
- .file-upload-help,
394
- .file-upload-invalid {
395
- font: var(--bl-font-body-3-regular, 0.75rem 400);
396
- margin: 0;
397
- }
398
-
399
- .file-upload-help {
400
- color: var(--bl-color-neutral-subtle, #6b7280);
401
- }
402
-
403
- .file-upload-invalid {
404
- color: var(--bl-color-danger, #dc2626);
405
- }
406
-
407
- .file-upload-list {
408
- display: flex;
409
- flex-wrap: wrap;
410
- gap: var(--bl-spacing-2, 0.5rem);
411
- }
412
-
413
- .file-upload-item {
414
- display: flex;
415
- flex-direction: column;
416
- align-items: flex-start;
417
- gap: var(--bl-spacing-1, 0.25rem);
418
- }
419
-
420
- .file-upload-preview {
421
- width: 48px;
422
- height: 48px;
423
- border-radius: var(--bl-radius-s, 4px);
424
- overflow: hidden;
425
- background: var(--bl-color-neutral-light, #e5e7eb);
426
- }
427
-
428
- .file-upload-thumb {
429
- width: 100%;
430
- height: 100%;
431
- object-fit: cover;
432
- }
433
-
434
- .file-upload-tag {
435
- max-width: 240px;
436
- overflow: hidden;
437
- text-overflow: ellipsis;
438
- white-space: nowrap;
439
- }
440
- </style>
@@ -1,89 +0,0 @@
1
- /**
2
- * File upload size.
3
- */
4
- export type FileUploadSize = "small" | "medium" | "large";
5
-
6
- /**
7
- * Validation failure reason.
8
- */
9
- export type FileUploadInvalidReason = "type" | "size" | "count";
10
-
11
- /**
12
- * Invalid file entry emitted on validation failure.
13
- */
14
- export interface FileUploadInvalidEntry {
15
- file: File;
16
- reason: FileUploadInvalidReason;
17
- }
18
-
19
- /**
20
- * Props for the FileUpload component.
21
- *
22
- * A custom file upload component with drag-and-drop, validation,
23
- * file list with remove, and optional preview.
24
- *
25
- * @interface FileUploadProps
26
- */
27
- export interface FileUploadProps {
28
- /**
29
- * Bound files (v-model). Single file or array when multiple.
30
- */
31
- modelValue?: File | File[] | null;
32
-
33
- /**
34
- * Allow multiple files.
35
- */
36
- multiple?: boolean;
37
-
38
- /**
39
- * Accepted MIME types or extensions (e.g. `image/*`, `.pdf`, `application/pdf`).
40
- */
41
- accept?: string;
42
-
43
- /**
44
- * Maximum file size in bytes.
45
- */
46
- maxSize?: number;
47
-
48
- /**
49
- * Minimum file size in bytes.
50
- */
51
- minSize?: number;
52
-
53
- /**
54
- * Maximum number of files when multiple is true.
55
- */
56
- maxFiles?: number;
57
-
58
- /**
59
- * Disabled state.
60
- */
61
- disabled?: boolean;
62
-
63
- /**
64
- * Label for the upload area.
65
- */
66
- label?: string;
67
-
68
- /**
69
- * Helper text below the upload area.
70
- */
71
- helpText?: string;
72
-
73
- /**
74
- * Error message when validation fails.
75
- */
76
- invalidText?: string;
77
-
78
- /**
79
- * Show image previews for image files.
80
- */
81
- showPreview?: boolean;
82
-
83
- /**
84
- * Drop zone size (small, medium, large).
85
- *
86
- * @default "medium"
87
- */
88
- size?: FileUploadSize;
89
- }
@@ -1,7 +0,0 @@
1
- export { default as BvFileUpload } from "./FileUpload.vue";
2
- export type {
3
- FileUploadProps,
4
- FileUploadSize,
5
- FileUploadInvalidReason,
6
- FileUploadInvalidEntry,
7
- } from "./file-upload.types";
package/src/icon/Icon.vue DELETED
@@ -1,102 +0,0 @@
1
- <script setup lang="ts">
2
- /**
3
- * Icon Component
4
- *
5
- * A Vue UI kit component for Baklava's `bl-icon` web component.
6
- * Provides icon display with support for name, size, color, and custom slot content.
7
- * Size and color are applied via CSS (font-size, color) as per Baklava's API.
8
- *
9
- * @component
10
- * @example
11
- * ```vue
12
- * <!-- Basic usage -->
13
- * <template>
14
- * <BvIcon name="home" />
15
- * </template>
16
- * ```
17
- *
18
- * @example
19
- * ```vue
20
- * <!-- With size -->
21
- * <template>
22
- * <BvIcon name="settings" size="24px" />
23
- * </template>
24
- * ```
25
- *
26
- * @example
27
- * ```vue
28
- * <!-- With color -->
29
- * <template>
30
- * <BvIcon name="info" color="#0066cc" />
31
- * </template>
32
- * ```
33
- *
34
- * @example
35
- * ```vue
36
- * <!-- Custom slot for custom SVG -->
37
- * <template>
38
- * <BvIcon>
39
- * <svg>...</svg>
40
- * </BvIcon>
41
- * </template>
42
- * ```
43
- */
44
- import { computed, onMounted } from "vue";
45
- import { loadBaklavaResources } from "../utils/loadBaklavaResources";
46
- import type { IconProps } from "./icon.types";
47
-
48
- /**
49
- * Component props with default values.
50
- */
51
- const props = withDefaults(defineProps<IconProps>(), {
52
- name: undefined,
53
- size: undefined,
54
- color: undefined,
55
- });
56
-
57
- /**
58
- * Component events.
59
- */
60
- const emit = defineEmits<{
61
- /**
62
- * Emitted when the SVG icon has loaded.
63
- *
64
- * @param {string} detail - Event detail from bl-load.
65
- */
66
- load: [detail: string];
67
- /**
68
- * Emitted when the SVG icon failed to load.
69
- *
70
- * @param {string} detail - Event detail from bl-error.
71
- */
72
- error: [detail: string];
73
- }>();
74
-
75
- /**
76
- * Computed style object for size and color.
77
- * Maps to Baklava's font-size and color CSS properties.
78
- */
79
- const iconStyle = computed(() => ({
80
- ...(props.size && { fontSize: props.size }),
81
- ...(props.color && { color: props.color }),
82
- }));
83
-
84
- /**
85
- * Lifecycle hook: Component mounted.
86
- * Loads Baklava resources (icons, styles).
87
- */
88
- onMounted(() => {
89
- loadBaklavaResources();
90
- });
91
- </script>
92
-
93
- <template>
94
- <bl-icon
95
- :name="props.name"
96
- :style="iconStyle"
97
- @bl-load="emit('load', ($event as CustomEvent<string>).detail)"
98
- @bl-error="emit('error', ($event as CustomEvent<string>).detail)"
99
- >
100
- <slot />
101
- </bl-icon>
102
- </template>
@@ -1,25 +0,0 @@
1
- import type { BaklavaIcon } from "@trendyol/baklava-icons";
2
-
3
- /**
4
- * Props for the Icon component.
5
- * Wraps Baklava's bl-icon web component with Vue-friendly props.
6
- */
7
- export interface IconProps {
8
- /**
9
- * Icon name from Baklava icons set.
10
- * @see https://baklava.trendyol.com for available icons.
11
- */
12
- name?: BaklavaIcon;
13
-
14
- /**
15
- * Icon size as a CSS value (e.g. `"24px"`, `"1.5rem"`).
16
- * Maps to the `font-size` CSS property on bl-icon.
17
- */
18
- size?: string;
19
-
20
- /**
21
- * Icon color as a CSS value (e.g. `"#0066cc"`, `"red"`, `"currentColor"`).
22
- * Maps to the `color` CSS property on bl-icon.
23
- */
24
- color?: string;
25
- }
package/src/icon/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { default as BvIcon } from "./Icon.vue";
2
- export type { IconProps } from "./icon.types";