ics-ui-kit 0.1.5 → 0.1.7

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 (32) hide show
  1. package/dist/components/file-upload/FileUpload.d.ts +1 -0
  2. package/dist/components/file-upload/FileUpload.stories.d.ts +1 -0
  3. package/dist/components/file-upload/components/file-upload-compact-input-zone/FileUploadCompactInputZone.d.ts +1 -1
  4. package/dist/components/file-upload/components/file-upload-input-zone/FileUploadInputZone.d.ts +1 -1
  5. package/dist/components/file-upload/components/file-upload-item/FileUploadItem.d.ts +2 -0
  6. package/dist/components/file-upload/components/file-upload-item/FileUploadItem.stories.d.ts +1 -0
  7. package/dist/components/file-upload/components/file-upload-item-compact/FileUploadItemCompact.d.ts +2 -0
  8. package/dist/components/file-upload/components/file-upload-item-compact/FileUploadItemCompact.stories.d.ts +1 -0
  9. package/dist/components/file-upload/file-upload-compact/FileUploadCompact.d.ts +1 -0
  10. package/dist/components/file-upload/file-upload-compact/FileUploadCompact.stories.d.ts +1 -0
  11. package/dist/components/file-upload.js +194 -185
  12. package/dist/components/file-upload.js.map +1 -1
  13. package/dist/components/resizable/components/ResizableCornerIcon.d.ts +3 -0
  14. package/dist/components/resizable/components/ResizableCornerIcon.stories.d.ts +7 -0
  15. package/dist/components/resizable/index.d.ts +1 -0
  16. package/dist/components/resizable.js +255 -232
  17. package/dist/components/resizable.js.map +1 -1
  18. package/dist/formatBytes-C4QXq5lC.js +9 -0
  19. package/dist/formatBytes-C4QXq5lC.js.map +1 -0
  20. package/dist/hooks/use-file-upload.js +1 -1
  21. package/dist/lib/utils/index.d.ts +1 -0
  22. package/dist/lib/utils.js +4 -2
  23. package/dist/lib/utils.js.map +1 -1
  24. package/dist/styles-scoped.css +10 -2
  25. package/dist/styles.css +10 -2
  26. package/dist/theme.css +2 -0
  27. package/dist/useFileUpload-Bnl3P8mP.js +193 -0
  28. package/dist/useFileUpload-Bnl3P8mP.js.map +1 -0
  29. package/package.json +1 -1
  30. package/tailwind.preset.js +4 -3
  31. package/dist/useFileUpload-iDag0iqM.js +0 -197
  32. package/dist/useFileUpload-iDag0iqM.js.map +0 -1
@@ -0,0 +1,9 @@
1
+ const e = (t, o = 2) => {
2
+ if (t === 0) return "0 Bytes";
3
+ const B = 1024, s = o < 0 ? 0 : o, a = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], r = Math.floor(Math.log(t) / Math.log(B));
4
+ return `${Number.parseFloat((t / Math.pow(B, r)).toFixed(s))} ${a[r]}`;
5
+ };
6
+ export {
7
+ e as f
8
+ };
9
+ //# sourceMappingURL=formatBytes-C4QXq5lC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatBytes-C4QXq5lC.js","sources":["../src/lib/utils/file/formatBytes.ts"],"sourcesContent":["// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n\tif (bytes === 0) return \"0 Bytes\";\n\n\tconst k = 1024;\n\tconst dm = decimals < 0 ? 0 : decimals;\n\tconst sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\n\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\n\treturn `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n};\n"],"names":["formatBytes","bytes","decimals","k","dm","sizes","i"],"mappings":"AACO,MAAMA,IAAc,CAACC,GAAeC,IAAW,MAAc;AAC/D,MAAAD,MAAU,EAAU,QAAA;AAExB,QAAME,IAAI,MACJC,IAAKF,IAAW,IAAI,IAAIA,GACxBG,IAAQ,CAAC,SAAS,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,GAEhEC,IAAI,KAAK,MAAM,KAAK,IAAIL,CAAK,IAAI,KAAK,IAAIE,CAAC,CAAC;AAElD,SAAO,GAAG,OAAO,YAAYF,IAAQ,KAAK,IAAIE,GAAGG,CAAC,GAAG,QAAQF,CAAE,CAAC,CAAC,IAAIC,EAAMC,CAAC,CAAC;AAC9E;"}
@@ -1,4 +1,4 @@
1
- import { d as e, a as r, u as o } from "../useFileUpload-iDag0iqM.js";
1
+ import { d as e, a as r, u as o } from "../useFileUpload-Bnl3P8mP.js";
2
2
  export {
3
3
  e as defaultErrorMessages,
4
4
  r as defaultErrorMessagesRu,
@@ -1,2 +1,3 @@
1
1
  export { formatCounterValue } from './formatCounterValue';
2
2
  export { cn } from './cn';
3
+ export { formatBytes } from './file/formatBytes';
package/dist/lib/utils.js CHANGED
@@ -1,4 +1,5 @@
1
- import { c as o } from "../cn-dsXlqdJg.js";
1
+ import { c as i } from "../cn-dsXlqdJg.js";
2
+ import { f as c } from "../formatBytes-C4QXq5lC.js";
2
3
  function n(r) {
3
4
  if (r === 0 || r < 0)
4
5
  return "";
@@ -19,7 +20,8 @@ function n(r) {
19
20
  return String(r);
20
21
  }
21
22
  export {
22
- o as cn,
23
+ i as cn,
24
+ c as formatBytes,
23
25
  n as formatCounterValue
24
26
  };
25
27
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/lib/utils/formatCounterValue.ts"],"sourcesContent":["/**\n * Форматирует число для отображения в компоненте Counter согласно правилам:\n * - Максимум 4 символа, включая `+`\n * - 0 не отображается\n * - Без дробей\n *\n * @param value - Число для форматирования\n * @returns Отформатированная строка или пустая строка для 0\n *\n * @example\n * formatCounterValue(5) // \"5\"\n * formatCounterValue(42) // \"42\"\n * formatCounterValue(150) // \"99+\"\n * formatCounterValue(5000) // \"999+\"\n * formatCounterValue(50000) // \"10k+\"\n * formatCounterValue(2000000) // \"2М+\"\n * formatCounterValue(10000000) // \"10М+\"\n * formatCounterValue(99000000) // \"99М+\"\n * formatCounterValue(0) // \"\"\n */\nexport function formatCounterValue(value: number): string {\n\t// 0 не отображаем\n\tif (value === 0) {\n\t\treturn \"\";\n\t}\n\n\t// Отрицательные числа не поддерживаются\n\tif (value < 0) {\n\t\treturn \"\";\n\t}\n\n\t// 1-9: показать одну цифру\n\tif (value >= 1 && value <= 9) {\n\t\treturn String(value);\n\t}\n\n\t// 10-99: показать две цифры\n\tif (value >= 10 && value <= 99) {\n\t\treturn String(value);\n\t}\n\n\t// 100-999: показать \"99+\"\n\tif (value >= 100 && value <= 999) {\n\t\treturn \"99+\";\n\t}\n\n\t// 1 000-9 999: показать \"999+\"\n\tif (value >= 1000 && value <= 9999) {\n\t\treturn \"999+\";\n\t}\n\n\t// 10 000-999 999: показать \"10k+\", \"99k+\" и т.д.\n\tif (value >= 10000 && value <= 999999) {\n\t\tconst thousands = Math.floor(value / 1000);\n\t\t// Проверяем, что результат не превышает 4 символа\n\t\tif (thousands <= 99) {\n\t\t\treturn `${thousands}k+`;\n\t\t}\n\t\t// Если больше 99k, показываем 99k+\n\t\treturn \"99k+\";\n\t}\n\n\t// ≥ 1 000 000: показать \"1М+\", \"9М+\", \"10М+\", \"99М+\" и т.д.\n\tif (value >= 1000000) {\n\t\tconst millions = Math.floor(value / 1000000);\n\t\t// 1-9 млн и 10-98 млн\"\n\t\tif ((millions >= 1 && millions <= 9) || (millions >= 10 && millions <= 98)) {\n\t\t\treturn `${millions}М+`;\n\t\t}\n\t\t// 99 млн и выше: всегда \"99М+\"\n\t\treturn \"99М+\";\n\t}\n\n\t// Fallback (не должно произойти)\n\treturn String(value);\n}\n"],"names":["formatCounterValue","value","thousands","millions"],"mappings":";AAoBO,SAASA,EAAmBC,GAAuB;AAOzD,MALIA,MAAU,KAKVA,IAAQ;AACJ,WAAA;AASJ,MALAA,KAAS,KAAKA,KAAS,KAKvBA,KAAS,MAAMA,KAAS;AAC3B,WAAO,OAAOA,CAAK;AAIhB,MAAAA,KAAS,OAAOA,KAAS;AACrB,WAAA;AAIJ,MAAAA,KAAS,OAAQA,KAAS;AACtB,WAAA;AAIJ,MAAAA,KAAS,OAASA,KAAS,QAAQ;AACtC,UAAMC,IAAY,KAAK,MAAMD,IAAQ,GAAI;AAEzC,WAAIC,KAAa,KACT,GAAGA,CAAS,OAGb;AAAA,EAAA;AAIR,MAAID,KAAS,KAAS;AACrB,UAAME,IAAW,KAAK,MAAMF,IAAQ,GAAO;AAE3C,WAAKE,KAAY,KAAKA,KAAY,KAAOA,KAAY,MAAMA,KAAY,KAC/D,GAAGA,CAAQ,OAGZ;AAAA,EAAA;AAIR,SAAO,OAAOF,CAAK;AACpB;"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/lib/utils/formatCounterValue.ts"],"sourcesContent":["/**\n * Форматирует число для отображения в компоненте Counter согласно правилам:\n * - Максимум 4 символа, включая `+`\n * - 0 не отображается\n * - Без дробей\n *\n * @param value - Число для форматирования\n * @returns Отформатированная строка или пустая строка для 0\n *\n * @example\n * formatCounterValue(5) // \"5\"\n * formatCounterValue(42) // \"42\"\n * formatCounterValue(150) // \"99+\"\n * formatCounterValue(5000) // \"999+\"\n * formatCounterValue(50000) // \"10k+\"\n * formatCounterValue(2000000) // \"2М+\"\n * formatCounterValue(10000000) // \"10М+\"\n * formatCounterValue(99000000) // \"99М+\"\n * formatCounterValue(0) // \"\"\n */\nexport function formatCounterValue(value: number): string {\n\t// 0 не отображаем\n\tif (value === 0) {\n\t\treturn \"\";\n\t}\n\n\t// Отрицательные числа не поддерживаются\n\tif (value < 0) {\n\t\treturn \"\";\n\t}\n\n\t// 1-9: показать одну цифру\n\tif (value >= 1 && value <= 9) {\n\t\treturn String(value);\n\t}\n\n\t// 10-99: показать две цифры\n\tif (value >= 10 && value <= 99) {\n\t\treturn String(value);\n\t}\n\n\t// 100-999: показать \"99+\"\n\tif (value >= 100 && value <= 999) {\n\t\treturn \"99+\";\n\t}\n\n\t// 1 000-9 999: показать \"999+\"\n\tif (value >= 1000 && value <= 9999) {\n\t\treturn \"999+\";\n\t}\n\n\t// 10 000-999 999: показать \"10k+\", \"99k+\" и т.д.\n\tif (value >= 10000 && value <= 999999) {\n\t\tconst thousands = Math.floor(value / 1000);\n\t\t// Проверяем, что результат не превышает 4 символа\n\t\tif (thousands <= 99) {\n\t\t\treturn `${thousands}k+`;\n\t\t}\n\t\t// Если больше 99k, показываем 99k+\n\t\treturn \"99k+\";\n\t}\n\n\t// ≥ 1 000 000: показать \"1М+\", \"9М+\", \"10М+\", \"99М+\" и т.д.\n\tif (value >= 1000000) {\n\t\tconst millions = Math.floor(value / 1000000);\n\t\t// 1-9 млн и 10-98 млн\"\n\t\tif ((millions >= 1 && millions <= 9) || (millions >= 10 && millions <= 98)) {\n\t\t\treturn `${millions}М+`;\n\t\t}\n\t\t// 99 млн и выше: всегда \"99М+\"\n\t\treturn \"99М+\";\n\t}\n\n\t// Fallback (не должно произойти)\n\treturn String(value);\n}\n"],"names":["formatCounterValue","value","thousands","millions"],"mappings":";;AAoBO,SAASA,EAAmBC,GAAuB;AAOzD,MALIA,MAAU,KAKVA,IAAQ;AACJ,WAAA;AASJ,MALAA,KAAS,KAAKA,KAAS,KAKvBA,KAAS,MAAMA,KAAS;AAC3B,WAAO,OAAOA,CAAK;AAIhB,MAAAA,KAAS,OAAOA,KAAS;AACrB,WAAA;AAIJ,MAAAA,KAAS,OAAQA,KAAS;AACtB,WAAA;AAIJ,MAAAA,KAAS,OAASA,KAAS,QAAQ;AACtC,UAAMC,IAAY,KAAK,MAAMD,IAAQ,GAAI;AAEzC,WAAIC,KAAa,KACT,GAAGA,CAAS,OAGb;AAAA,EAAA;AAIR,MAAID,KAAS,KAAS;AACrB,UAAME,IAAW,KAAK,MAAMF,IAAQ,GAAO;AAE3C,WAAKE,KAAY,KAAKA,KAAY,KAAOA,KAAY,MAAMA,KAAY,KAC/D,GAAGA,CAAQ,OAGZ;AAAA,EAAA;AAIR,SAAO,OAAOF,CAAK;AACpB;"}
@@ -181,6 +181,7 @@
181
181
 
182
182
  --shadow-glass-sm: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 0 40px 30px -40px rgba(0, 0, 0, 0.16) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-secondary-border, #E4E4E7), 0 8px 16px 0 rgba(0, 0, 0, 0.02);
183
183
  --shadow-glass-md: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-primary-border, #D4D4D8), 0 4px 24px 0 rgba(0, 0, 0, 0.12);
184
+ --shadow-glass-lg: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-secondary-border, #E4E4E7), 0 8px 16px 0 rgba(0, 0, 0, 0.02);
184
185
  }
185
186
  .dark {
186
187
  /**
@@ -344,6 +345,7 @@
344
345
 
345
346
  --shadow-glass-sm: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -40px 80px -40px rgba(255, 255, 255, 0.30) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 16px 0 rgba(0, 0, 0, 0.04);
346
347
  --shadow-glass-md: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -20px 250px -100px rgba(255, 255, 255, 0.20) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 48px 0 rgba(0, 0, 0, 0.48);
348
+ --shadow-glass-lg: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -20px 250px -100px rgba(255, 255, 255, 0.20) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 16px 0 rgba(0, 0, 0, 0.04);
347
349
  }
348
350
  .backdrop-glass-clear {
349
351
  backdrop-filter: var(--glass-clear);
@@ -1440,6 +1442,9 @@
1440
1442
  .ui-kit .right-0 {
1441
1443
  right: 0px;
1442
1444
  }
1445
+ .ui-kit .right-0\.5 {
1446
+ right: 0.125rem;
1447
+ }
1443
1448
  .ui-kit .right-1 {
1444
1449
  right: 0.25rem;
1445
1450
  }
@@ -3002,13 +3007,13 @@
3002
3007
  background-color: hsl(var(--alpha-50));
3003
3008
  }
3004
3009
  .ui-kit .bg-alpha-60 {
3005
- background-color: hsl(var(--alpha-50));
3010
+ background-color: hsl(var(--alpha-40));
3006
3011
  }
3007
3012
  .ui-kit .bg-alpha-high-20 {
3008
3013
  background-color: hsl(var(--alpha-high-80));
3009
3014
  }
3010
3015
  .ui-kit .bg-alpha-high-60 {
3011
- background-color: hsl(var(--alpha-high-50));
3016
+ background-color: hsl(var(--alpha-high-40));
3012
3017
  }
3013
3018
  .ui-kit .bg-alpha-high-80 {
3014
3019
  background-color: hsl(var(--alpha-high-20));
@@ -6103,6 +6108,9 @@
6103
6108
  visibility: visible;
6104
6109
  }
6105
6110
  }
6111
+ .ui-kit .\[\&\:\:-webkit-resizer\]\:appearance-none::-webkit-resizer {
6112
+ appearance: none;
6113
+ }
6106
6114
  .ui-kit .\[\&\:\:-webkit-search-cancel-button\]\:hidden::-webkit-search-cancel-button {
6107
6115
  display: none;
6108
6116
  }
package/dist/styles.css CHANGED
@@ -181,6 +181,7 @@
181
181
 
182
182
  --shadow-glass-sm: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 0 40px 30px -40px rgba(0, 0, 0, 0.16) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-secondary-border, #E4E4E7), 0 8px 16px 0 rgba(0, 0, 0, 0.02);
183
183
  --shadow-glass-md: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-primary-border, #D4D4D8), 0 4px 24px 0 rgba(0, 0, 0, 0.12);
184
+ --shadow-glass-lg: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-secondary-border, #E4E4E7), 0 8px 16px 0 rgba(0, 0, 0, 0.02);
184
185
  }
185
186
  .dark {
186
187
  /**
@@ -344,6 +345,7 @@
344
345
 
345
346
  --shadow-glass-sm: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -40px 80px -40px rgba(255, 255, 255, 0.30) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 16px 0 rgba(0, 0, 0, 0.04);
346
347
  --shadow-glass-md: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -20px 250px -100px rgba(255, 255, 255, 0.20) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 48px 0 rgba(0, 0, 0, 0.48);
348
+ --shadow-glass-lg: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -20px 250px -100px rgba(255, 255, 255, 0.20) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 16px 0 rgba(0, 0, 0, 0.04);
347
349
  }
348
350
  .backdrop-glass-clear {
349
351
  backdrop-filter: var(--glass-clear);
@@ -1425,6 +1427,9 @@ body {
1425
1427
  .right-0 {
1426
1428
  right: 0px;
1427
1429
  }
1430
+ .right-0\.5 {
1431
+ right: 0.125rem;
1432
+ }
1428
1433
  .right-1 {
1429
1434
  right: 0.25rem;
1430
1435
  }
@@ -2987,13 +2992,13 @@ body {
2987
2992
  background-color: hsl(var(--alpha-50));
2988
2993
  }
2989
2994
  .bg-alpha-60 {
2990
- background-color: hsl(var(--alpha-50));
2995
+ background-color: hsl(var(--alpha-40));
2991
2996
  }
2992
2997
  .bg-alpha-high-20 {
2993
2998
  background-color: hsl(var(--alpha-high-80));
2994
2999
  }
2995
3000
  .bg-alpha-high-60 {
2996
- background-color: hsl(var(--alpha-high-50));
3001
+ background-color: hsl(var(--alpha-high-40));
2997
3002
  }
2998
3003
  .bg-alpha-high-80 {
2999
3004
  background-color: hsl(var(--alpha-high-20));
@@ -6092,6 +6097,9 @@ body {
6092
6097
  visibility: visible;
6093
6098
  }
6094
6099
  }
6100
+ .\[\&\:\:-webkit-resizer\]\:appearance-none::-webkit-resizer {
6101
+ appearance: none;
6102
+ }
6095
6103
  .\[\&\:\:-webkit-search-cancel-button\]\:hidden::-webkit-search-cancel-button {
6096
6104
  display: none;
6097
6105
  }
package/dist/theme.css CHANGED
@@ -180,6 +180,7 @@
180
180
 
181
181
  --shadow-glass-sm: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 0 40px 30px -40px rgba(0, 0, 0, 0.16) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-secondary-border, #E4E4E7), 0 8px 16px 0 rgba(0, 0, 0, 0.02);
182
182
  --shadow-glass-md: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-primary-border, #D4D4D8), 0 4px 24px 0 rgba(0, 0, 0, 0.12);
183
+ --shadow-glass-lg: 0 1.5px 1.5px -0.5px rgb(255, 255, 255) inset, 0 -6px 3px -3px rgb(255, 255, 255) inset, 1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), -1.25px 0 0 -0.75px var(--tailwind-colors-zinc-400, #A1A1AA), 0 0 0 0.5px var(--base-secondary-border, #E4E4E7), 0 8px 16px 0 rgba(0, 0, 0, 0.02);
183
184
  }
184
185
 
185
186
  .dark {
@@ -344,6 +345,7 @@
344
345
 
345
346
  --shadow-glass-sm: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -40px 80px -40px rgba(255, 255, 255, 0.30) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 16px 0 rgba(0, 0, 0, 0.04);
346
347
  --shadow-glass-md: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -20px 250px -100px rgba(255, 255, 255, 0.20) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 48px 0 rgba(0, 0, 0, 0.48);
348
+ --shadow-glass-lg: 0 1px 1px -0.5px rgba(255, 255, 255, 0.40) inset, 0 -1px 1px -0.5px rgba(255, 255, 255, 0.30) inset, 0 -20px 250px -100px rgba(255, 255, 255, 0.20) inset, 1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), -1.25px 0 0 -0.75px rgba(0, 0, 0, 0.50), 0 0 0 0.5px rgba(0, 0, 0, 0.50), 0 8px 16px 0 rgba(0, 0, 0, 0.04);
347
349
  }
348
350
 
349
351
  .backdrop-glass-clear {
@@ -0,0 +1,193 @@
1
+ import { useMemo as W, useState as k, useRef as O, useCallback as n } from "react";
2
+ import { f as h } from "./formatBytes-C4QXq5lC.js";
3
+ const j = {
4
+ fileTooLarge: (s, c) => `File "${s}" exceeds the maximum size of ${h(c)}.`,
5
+ invalidFileType: (s) => `File "${s}" is not an accepted file type.`,
6
+ tooManyFiles: (s) => `You can only upload a maximum of ${s} files.`,
7
+ someFilesTooLarge: (s) => `Some files exceed the maximum size of ${h(s)}.`,
8
+ singleFileTooLarge: (s) => `File exceeds the maximum size of ${h(s)}.`
9
+ }, N = {
10
+ fileTooLarge: (s, c) => `Файл "${s}" превышает максимальный размер ${h(c)}`,
11
+ invalidFileType: (s) => `Файл "${s}" имеет недопустимый тип`,
12
+ tooManyFiles: (s) => `Можно загрузить максимум ${s} файлов`,
13
+ someFilesTooLarge: (s) => `Некоторые файлы превышают максимальный размер ${h(s)}`,
14
+ singleFileTooLarge: (s) => `Файл превышает максимальный размер ${h(s)}`
15
+ }, Y = (s = {}) => {
16
+ const {
17
+ maxFiles: c = 1 / 0,
18
+ maxSize: g = 1 / 0,
19
+ accept: T = "*",
20
+ multiple: o = !1,
21
+ initialFiles: z = [],
22
+ onFilesChange: m,
23
+ onFilesAdded: D,
24
+ errorMessages: w
25
+ } = s, p = W(() => ({ ...j, ...w }), [w]), [v, l] = k({
26
+ files: z.map((e) => ({
27
+ file: e,
28
+ id: e.id,
29
+ preview: e.url
30
+ })),
31
+ isDragging: !1,
32
+ errors: []
33
+ }), f = O(null), x = n(
34
+ (e) => {
35
+ const r = (e instanceof File, e.name);
36
+ if (e.size > g)
37
+ return p.fileTooLarge(r, g);
38
+ if (T !== "*") {
39
+ const i = T.split(",").map((u) => u.trim()), a = e instanceof File ? e.type || "" : e.type, t = `.${r.split(".").pop()}`;
40
+ if (!i.some((u) => {
41
+ if (u.startsWith("."))
42
+ return t.toLowerCase() === u.toLowerCase();
43
+ if (u.endsWith("/*")) {
44
+ const y = u.split("/")[0];
45
+ return a.startsWith(`${y}/`);
46
+ }
47
+ return a === u;
48
+ }))
49
+ return p.invalidFileType(r);
50
+ }
51
+ return null;
52
+ },
53
+ [T, g, p]
54
+ ), M = n((e) => e instanceof File ? URL.createObjectURL(e) : e.url, []), R = n((e) => e instanceof File ? `${e.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}` : e.id, []), L = n(() => {
55
+ l((e) => {
56
+ e.files.forEach((i) => {
57
+ i.preview && i.file instanceof File && i.file.type.startsWith("image/") && URL.revokeObjectURL(i.preview);
58
+ }), f.current && (f.current.value = "");
59
+ const r = {
60
+ ...e,
61
+ files: [],
62
+ errors: []
63
+ };
64
+ return m?.(r.files), r;
65
+ });
66
+ }, [m]), d = n(
67
+ (e) => {
68
+ if (!e || e.length === 0) return;
69
+ const r = Array.from(e), i = [];
70
+ if (l((t) => ({ ...t, errors: [] })), o || L(), o && c !== 1 / 0 && v.files.length + r.length > c) {
71
+ i.push(p.tooManyFiles(c)), l((t) => ({ ...t, errors: i }));
72
+ return;
73
+ }
74
+ const a = [];
75
+ r.forEach((t) => {
76
+ if (o && v.files.some(
77
+ (y) => y.file.name === t.name && y.file.size === t.size
78
+ ))
79
+ return;
80
+ if (t.size > g) {
81
+ i.push(
82
+ o ? p.someFilesTooLarge(g) : p.singleFileTooLarge(g)
83
+ );
84
+ return;
85
+ }
86
+ const F = x(t);
87
+ F ? i.push(F) : a.push({
88
+ file: t,
89
+ id: R(t),
90
+ preview: M(t)
91
+ });
92
+ }), a.length > 0 ? (D?.(a), l((t) => {
93
+ const F = o ? [...t.files, ...a] : a;
94
+ return m?.(F), {
95
+ ...t,
96
+ files: F,
97
+ errors: i
98
+ };
99
+ })) : i.length > 0 && l((t) => ({
100
+ ...t,
101
+ errors: i
102
+ })), f.current && (f.current.value = "");
103
+ },
104
+ [
105
+ v.files,
106
+ c,
107
+ o,
108
+ g,
109
+ x,
110
+ M,
111
+ R,
112
+ L,
113
+ m,
114
+ D,
115
+ p
116
+ ]
117
+ ), E = n(
118
+ (e) => {
119
+ l((r) => {
120
+ const i = r.files.find((t) => t.id === e);
121
+ i && i.preview && i.file instanceof File && i.file.type.startsWith("image/") && URL.revokeObjectURL(i.preview);
122
+ const a = r.files.filter((t) => t.id !== e);
123
+ return m?.(a), {
124
+ ...r,
125
+ files: a,
126
+ errors: []
127
+ };
128
+ });
129
+ },
130
+ [m]
131
+ ), U = n(() => {
132
+ l((e) => ({
133
+ ...e,
134
+ errors: []
135
+ }));
136
+ }, []), b = n((e) => {
137
+ e.preventDefault(), e.stopPropagation(), l((r) => ({ ...r, isDragging: !0 }));
138
+ }, []), C = n((e) => {
139
+ e.preventDefault(), e.stopPropagation(), !e.currentTarget.contains(e.relatedTarget) && l((r) => ({ ...r, isDragging: !1 }));
140
+ }, []), P = n((e) => {
141
+ e.preventDefault(), e.stopPropagation();
142
+ }, []), S = n(
143
+ (e) => {
144
+ if (e.preventDefault(), e.stopPropagation(), l((r) => ({ ...r, isDragging: !1 })), !f.current?.disabled && e.dataTransfer.files && e.dataTransfer.files.length > 0)
145
+ if (o)
146
+ d(e.dataTransfer.files);
147
+ else {
148
+ const r = e.dataTransfer.files[0];
149
+ d([r]);
150
+ }
151
+ },
152
+ [d, o]
153
+ ), $ = n(
154
+ (e) => {
155
+ e.target.files && e.target.files.length > 0 && d(e.target.files);
156
+ },
157
+ [d]
158
+ ), A = n(() => {
159
+ f.current && f.current.click();
160
+ }, []), I = n(
161
+ (e = {}) => ({
162
+ ...e,
163
+ type: "file",
164
+ onChange: $,
165
+ accept: e.accept || T,
166
+ multiple: e.multiple !== void 0 ? e.multiple : o,
167
+ ref: f
168
+ }),
169
+ [T, o, $]
170
+ );
171
+ return [
172
+ v,
173
+ {
174
+ addFiles: d,
175
+ removeFile: E,
176
+ clearFiles: L,
177
+ clearErrors: U,
178
+ handleDragEnter: b,
179
+ handleDragLeave: C,
180
+ handleDragOver: P,
181
+ handleDrop: S,
182
+ handleFileChange: $,
183
+ openFileDialog: A,
184
+ getInputProps: I
185
+ }
186
+ ];
187
+ };
188
+ export {
189
+ N as a,
190
+ j as d,
191
+ Y as u
192
+ };
193
+ //# sourceMappingURL=useFileUpload-Bnl3P8mP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFileUpload-Bnl3P8mP.js","sources":["../src/hooks/use-file-upload/errorMessages.ts","../src/hooks/use-file-upload/useFileUpload.ts"],"sourcesContent":["import { formatBytes } from \"@/lib/utils/file/formatBytes\";\n\n/**\n * Интерфейс для кастомизации сообщений об ошибках в useFileUpload\n */\nexport interface FileUploadErrorMessages {\n\t/**\n\t * Сообщение когда файл превышает максимальный размер\n\t * @param fileName - имя файла\n\t * @param maxSizeBytes - максимальный размер в байтах\n\t */\n\tfileTooLarge?: (fileName: string, maxSizeBytes: number) => string;\n\n\t/**\n\t * Сообщение когда тип файла не разрешен\n\t * @param fileName - имя файла\n\t */\n\tinvalidFileType?: (fileName: string) => string;\n\n\t/**\n\t * Сообщение когда превышено максимальное количество файлов\n\t * @param maxFiles - максимальное количество файлов\n\t */\n\ttooManyFiles?: (maxFiles: number) => string;\n\n\t/**\n\t * Сообщение когда некоторые файлы превышают максимальный размер (для множественной загрузки)\n\t * @param maxSizeBytes - максимальный размер в байтах\n\t */\n\tsomeFilesTooLarge?: (maxSizeBytes: number) => string;\n\n\t/**\n\t * Сообщение когда файл превышает максимальный размер (для одиночной загрузки)\n\t * @param maxSizeBytes - максимальный размер в байтах\n\t */\n\tsingleFileTooLarge?: (maxSizeBytes: number) => string;\n}\n\n/**\n * Сообщения об ошибках по умолчанию\n */\nexport const defaultErrorMessages: Required<FileUploadErrorMessages> = {\n\tfileTooLarge: (fileName, maxSizeBytes) =>\n\t\t`File \"${fileName}\" exceeds the maximum size of ${formatBytes(maxSizeBytes)}.`,\n\tinvalidFileType: (fileName) => `File \"${fileName}\" is not an accepted file type.`,\n\ttooManyFiles: (maxFiles) => `You can only upload a maximum of ${maxFiles} files.`,\n\tsomeFilesTooLarge: (maxSizeBytes) => `Some files exceed the maximum size of ${formatBytes(maxSizeBytes)}.`,\n\tsingleFileTooLarge: (maxSizeBytes) => `File exceeds the maximum size of ${formatBytes(maxSizeBytes)}.`\n};\n\n/**\n * Сообщения об ошибках на русском языке\n */\nexport const defaultErrorMessagesRu: Required<FileUploadErrorMessages> = {\n\tfileTooLarge: (fileName, maxSizeBytes) =>\n\t\t`Файл \"${fileName}\" превышает максимальный размер ${formatBytes(maxSizeBytes)}`,\n\tinvalidFileType: (fileName) => `Файл \"${fileName}\" имеет недопустимый тип`,\n\ttooManyFiles: (maxFiles) => `Можно загрузить максимум ${maxFiles} файлов`,\n\tsomeFilesTooLarge: (maxSizeBytes) => `Некоторые файлы превышают максимальный размер ${formatBytes(maxSizeBytes)}`,\n\tsingleFileTooLarge: (maxSizeBytes) => `Файл превышает максимальный размер ${formatBytes(maxSizeBytes)}`\n};\n","import {\n\tuseCallback,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n\ttype ChangeEvent,\n\ttype DragEvent,\n\ttype InputHTMLAttributes\n} from \"react\";\nimport { defaultErrorMessages, type FileUploadErrorMessages } from \"./errorMessages\";\n\nexport type FileData = {\n\tname: string;\n\tsize: number;\n\ttype: string;\n\tid?: string;\n};\n\nexport type FileMetadata = FileData & {\n\turl: string;\n\tid: string;\n};\n\nexport type FileValue = File | FileData;\n\nexport type FileWithPreview = {\n\tfile: FileValue;\n\tid: string;\n\tpreview?: string;\n};\n\n/**\n * Ограничения для загрузки файлов\n */\nexport type FileUploadConstraints = {\n\t/**\n\t * Максимальное количество файлов\n\t * Используется только когда multiple=true\n\t * @default Infinity\n\t */\n\tmaxFiles?: number;\n\n\t/**\n\t * Максимальный размер файла в байтах\n\t * @default Infinity\n\t */\n\tmaxSize?: number;\n\n\t/**\n\t * Допустимые типы файлов (строка MIME-типов или расширений через запятую)\n\t * @example \"image/jpeg,image/png,.pdf,.doc\"\n\t * @example \"*.jpg,*.png\"\n\t * @example \"image/*\"\n\t * @default \"*\"\n\t */\n\taccept?: string;\n\n\t/**\n\t * Разрешить выбор нескольких файлов\n\t * @default false\n\t */\n\tmultiple?: boolean;\n};\n\nexport type FileUploadOptions = FileUploadConstraints & {\n\tinitialFiles?: FileMetadata[];\n\tonFilesChange?: (files: FileWithPreview[]) => void;\n\tonFilesAdded?: (addedFiles: FileWithPreview[]) => void;\n\t/**\n\t * Кастомные сообщения об ошибках\n\t * Можно переопределить только нужные сообщения\n\t */\n\terrorMessages?: Partial<FileUploadErrorMessages>;\n};\n\nexport type FileUploadState = {\n\tfiles: FileWithPreview[];\n\tisDragging: boolean;\n\terrors: string[];\n};\n\nexport type FileUploadActions = {\n\taddFiles: (files: FileList | File[]) => void;\n\tremoveFile: (id: string) => void;\n\tclearFiles: () => void;\n\tclearErrors: () => void;\n\thandleDragEnter: (e: DragEvent<HTMLElement>) => void;\n\thandleDragLeave: (e: DragEvent<HTMLElement>) => void;\n\thandleDragOver: (e: DragEvent<HTMLElement>) => void;\n\thandleDrop: (e: DragEvent<HTMLElement>) => void;\n\thandleFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\n\topenFileDialog: () => void;\n\tgetInputProps: (props?: InputHTMLAttributes<HTMLInputElement>) => InputHTMLAttributes<HTMLInputElement> & {\n\t\tref: React.Ref<HTMLInputElement>;\n\t};\n};\n\n/** Хук был взять из библиотеки originui.\n * Код можно посмотреть по ссылке: https://github.com/origin-space/originui/blob/main/docs/use-file-upload.md\n */\nexport const useFileUpload = (options: FileUploadOptions = {}): [FileUploadState, FileUploadActions] => {\n\tconst {\n\t\tmaxFiles = Infinity,\n\t\tmaxSize = Infinity,\n\t\taccept = \"*\",\n\t\tmultiple = false,\n\t\tinitialFiles = [],\n\t\tonFilesChange,\n\t\tonFilesAdded,\n\t\terrorMessages: customErrorMessages\n\t} = options;\n\n\t// Объединяем дефолтные и кастомные сообщения\n\tconst errorMessages = useMemo(() => ({ ...defaultErrorMessages, ...customErrorMessages }), [customErrorMessages]);\n\n\tconst [state, setState] = useState<FileUploadState>({\n\t\tfiles: initialFiles.map((file) => ({\n\t\t\tfile,\n\t\t\tid: file.id,\n\t\t\tpreview: file.url\n\t\t})),\n\t\tisDragging: false,\n\t\terrors: []\n\t});\n\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\n\tconst validateFile = useCallback(\n\t\t(file: FileValue): string | null => {\n\t\t\tconst fileName = file instanceof File ? file.name : file.name;\n\n\t\t\tif (file.size > maxSize) {\n\t\t\t\treturn errorMessages.fileTooLarge(fileName, maxSize);\n\t\t\t}\n\n\t\t\tif (accept !== \"*\") {\n\t\t\t\tconst acceptedTypes = accept.split(\",\").map((type) => type.trim());\n\t\t\t\tconst fileType = file instanceof File ? file.type || \"\" : file.type;\n\t\t\t\tconst fileExtension = `.${fileName.split(\".\").pop()}`;\n\n\t\t\t\tconst isAccepted = acceptedTypes.some((type) => {\n\t\t\t\t\tif (type.startsWith(\".\")) {\n\t\t\t\t\t\treturn fileExtension.toLowerCase() === type.toLowerCase();\n\t\t\t\t\t}\n\t\t\t\t\tif (type.endsWith(\"/*\")) {\n\t\t\t\t\t\tconst baseType = type.split(\"/\")[0];\n\t\t\t\t\t\treturn fileType.startsWith(`${baseType}/`);\n\t\t\t\t\t}\n\t\t\t\t\treturn fileType === type;\n\t\t\t\t});\n\n\t\t\t\tif (!isAccepted) {\n\t\t\t\t\treturn errorMessages.invalidFileType(fileName);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t},\n\t\t[accept, maxSize, errorMessages]\n\t);\n\n\tconst createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n\t\tif (file instanceof File) {\n\t\t\treturn URL.createObjectURL(file);\n\t\t}\n\t\treturn file.url;\n\t}, []);\n\n\tconst generateUniqueId = useCallback((file: File | FileMetadata): string => {\n\t\tif (file instanceof File) {\n\t\t\treturn `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n\t\t}\n\t\treturn file.id;\n\t}, []);\n\n\tconst clearFiles = useCallback(() => {\n\t\tsetState((prev) => {\n\t\t\t// Clean up object URLs\n\t\t\tprev.files.forEach((file) => {\n\t\t\t\tif (file.preview && file.file instanceof File && file.file.type.startsWith(\"image/\")) {\n\t\t\t\t\tURL.revokeObjectURL(file.preview);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (inputRef.current) {\n\t\t\t\tinputRef.current.value = \"\";\n\t\t\t}\n\n\t\t\tconst newState = {\n\t\t\t\t...prev,\n\t\t\t\tfiles: [],\n\t\t\t\terrors: []\n\t\t\t};\n\n\t\t\tonFilesChange?.(newState.files);\n\t\t\treturn newState;\n\t\t});\n\t}, [onFilesChange]);\n\n\tconst addFiles = useCallback(\n\t\t(newFiles: FileList | File[]) => {\n\t\t\tif (!newFiles || newFiles.length === 0) return;\n\n\t\t\tconst newFilesArray = Array.from(newFiles);\n\t\t\tconst errors: string[] = [];\n\n\t\t\t// Clear existing errors when new files are uploaded\n\t\t\tsetState((prev) => ({ ...prev, errors: [] }));\n\n\t\t\t// In single file mode, clear existing files first\n\t\t\tif (!multiple) {\n\t\t\t\tclearFiles();\n\t\t\t}\n\n\t\t\t// Check if adding these files would exceed maxFiles (only in multiple mode)\n\t\t\tif (multiple && maxFiles !== Infinity && state.files.length + newFilesArray.length > maxFiles) {\n\t\t\t\terrors.push(errorMessages.tooManyFiles(maxFiles));\n\t\t\t\tsetState((prev) => ({ ...prev, errors }));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst validFiles: FileWithPreview[] = [];\n\n\t\t\tnewFilesArray.forEach((file) => {\n\t\t\t\t// Only check for duplicates if multiple files are allowed\n\t\t\t\tif (multiple) {\n\t\t\t\t\tconst isDuplicate = state.files.some(\n\t\t\t\t\t\t(existingFile) => existingFile.file.name === file.name && existingFile.file.size === file.size\n\t\t\t\t\t);\n\n\t\t\t\t\t// Skip duplicate files silently\n\t\t\t\t\tif (isDuplicate) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check file size\n\t\t\t\tif (file.size > maxSize) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\tmultiple ? errorMessages.someFilesTooLarge(maxSize) : errorMessages.singleFileTooLarge(maxSize)\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst error = validateFile(file);\n\t\t\t\tif (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t} else {\n\t\t\t\t\tvalidFiles.push({\n\t\t\t\t\t\tfile,\n\t\t\t\t\t\tid: generateUniqueId(file),\n\t\t\t\t\t\tpreview: createPreview(file)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Only update state if we have valid files to add\n\t\t\tif (validFiles.length > 0) {\n\t\t\t\t// Call the onFilesAdded callback with the newly added valid files\n\t\t\t\tonFilesAdded?.(validFiles);\n\n\t\t\t\tsetState((prev) => {\n\t\t\t\t\tconst newFiles = !multiple ? validFiles : [...prev.files, ...validFiles];\n\t\t\t\t\tonFilesChange?.(newFiles);\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\tfiles: newFiles,\n\t\t\t\t\t\terrors\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t} else if (errors.length > 0) {\n\t\t\t\tsetState((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\terrors\n\t\t\t\t}));\n\t\t\t}\n\n\t\t\t// Reset input value after handling files\n\t\t\tif (inputRef.current) {\n\t\t\t\tinputRef.current.value = \"\";\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tstate.files,\n\t\t\tmaxFiles,\n\t\t\tmultiple,\n\t\t\tmaxSize,\n\t\t\tvalidateFile,\n\t\t\tcreatePreview,\n\t\t\tgenerateUniqueId,\n\t\t\tclearFiles,\n\t\t\tonFilesChange,\n\t\t\tonFilesAdded,\n\t\t\terrorMessages\n\t\t]\n\t);\n\n\tconst removeFile = useCallback(\n\t\t(id: string) => {\n\t\t\tsetState((prev) => {\n\t\t\t\tconst fileToRemove = prev.files.find((file) => file.id === id);\n\t\t\t\tif (\n\t\t\t\t\tfileToRemove &&\n\t\t\t\t\tfileToRemove.preview &&\n\t\t\t\t\tfileToRemove.file instanceof File &&\n\t\t\t\t\tfileToRemove.file.type.startsWith(\"image/\")\n\t\t\t\t) {\n\t\t\t\t\tURL.revokeObjectURL(fileToRemove.preview);\n\t\t\t\t}\n\n\t\t\t\tconst newFiles = prev.files.filter((file) => file.id !== id);\n\t\t\t\tonFilesChange?.(newFiles);\n\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tfiles: newFiles,\n\t\t\t\t\terrors: []\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\t[onFilesChange]\n\t);\n\n\tconst clearErrors = useCallback(() => {\n\t\tsetState((prev) => ({\n\t\t\t...prev,\n\t\t\terrors: []\n\t\t}));\n\t}, []);\n\n\tconst handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\tsetState((prev) => ({ ...prev, isDragging: true }));\n\t}, []);\n\n\tconst handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\tif (e.currentTarget.contains(e.relatedTarget as Node)) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetState((prev) => ({ ...prev, isDragging: false }));\n\t}, []);\n\n\tconst handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t}, []);\n\n\tconst handleDrop = useCallback(\n\t\t(e: DragEvent<HTMLElement>) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tsetState((prev) => ({ ...prev, isDragging: false }));\n\n\t\t\t// Don't process files if the input is disabled\n\t\t\tif (inputRef.current?.disabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n\t\t\t\t// In single file mode, only use the first file\n\t\t\t\tif (!multiple) {\n\t\t\t\t\tconst file = e.dataTransfer.files[0];\n\t\t\t\t\taddFiles([file]);\n\t\t\t\t} else {\n\t\t\t\t\taddFiles(e.dataTransfer.files);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[addFiles, multiple]\n\t);\n\n\tconst handleFileChange = useCallback(\n\t\t(e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tif (e.target.files && e.target.files.length > 0) {\n\t\t\t\taddFiles(e.target.files);\n\t\t\t}\n\t\t},\n\t\t[addFiles]\n\t);\n\n\tconst openFileDialog = useCallback(() => {\n\t\tif (inputRef.current) {\n\t\t\tinputRef.current.click();\n\t\t}\n\t}, []);\n\n\tconst getInputProps = useCallback(\n\t\t(props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n\t\t\treturn {\n\t\t\t\t...props,\n\t\t\t\ttype: \"file\" as const,\n\t\t\t\tonChange: handleFileChange,\n\t\t\t\taccept: props.accept || accept,\n\t\t\t\tmultiple: props.multiple !== undefined ? props.multiple : multiple,\n\t\t\t\tref: inputRef\n\t\t\t};\n\t\t},\n\t\t[accept, multiple, handleFileChange]\n\t);\n\n\treturn [\n\t\tstate,\n\t\t{\n\t\t\taddFiles,\n\t\t\tremoveFile,\n\t\t\tclearFiles,\n\t\t\tclearErrors,\n\t\t\thandleDragEnter,\n\t\t\thandleDragLeave,\n\t\t\thandleDragOver,\n\t\t\thandleDrop,\n\t\t\thandleFileChange,\n\t\t\topenFileDialog,\n\t\t\tgetInputProps\n\t\t}\n\t];\n};\n"],"names":["defaultErrorMessages","fileName","maxSizeBytes","formatBytes","maxFiles","defaultErrorMessagesRu","useFileUpload","options","maxSize","accept","multiple","initialFiles","onFilesChange","onFilesAdded","customErrorMessages","errorMessages","useMemo","state","setState","useState","file","inputRef","useRef","validateFile","useCallback","acceptedTypes","type","fileType","fileExtension","baseType","createPreview","generateUniqueId","clearFiles","prev","newState","addFiles","newFiles","newFilesArray","errors","validFiles","existingFile","error","removeFile","id","fileToRemove","clearErrors","handleDragEnter","handleDragLeave","handleDragOver","handleDrop","handleFileChange","openFileDialog","getInputProps","props"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ics-ui-kit",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "packageManager": "pnpm@10.17.1",
5
5
  "repository": {
6
6
  "type": "git",
@@ -164,7 +164,7 @@ export default {
164
164
  30: "hsl(var(--alpha-70))",
165
165
  40: "hsl(var(--alpha-60))",
166
166
  50: "hsl(var(--alpha-50))",
167
- 60: "hsl(var(--alpha-50))",
167
+ 60: "hsl(var(--alpha-40))",
168
168
  70: "hsl(var(--alpha-30))",
169
169
  80: "hsl(var(--alpha-20))",
170
170
  90: "hsl(var(--alpha-10))",
@@ -178,7 +178,7 @@ export default {
178
178
  30: "hsl(var(--alpha-high-70))",
179
179
  40: "hsl(var(--alpha-high-60))",
180
180
  50: "hsl(var(--alpha-high-50))",
181
- 60: "hsl(var(--alpha-high-50))",
181
+ 60: "hsl(var(--alpha-high-40))",
182
182
  70: "hsl(var(--alpha-high-30))",
183
183
  80: "hsl(var(--alpha-high-20))",
184
184
  90: "hsl(var(--alpha-high-10))",
@@ -255,7 +255,8 @@ export default {
255
255
  "0 4px 6px 0 rgba(2, 6, 23, 0.35), 0 0 0.5px 0 rgba(255, 255, 255, 0.35) inset, 0 12px 28px 0 rgba(2, 6, 23, 0.45), 0 0.5px 0 0 rgba(255, 255, 255, 0.08) inset",
256
256
 
257
257
  "glass-sm": "var(--shadow-glass-sm)",
258
- "glass-md": "var(--shadow-glass-md)"
258
+ "glass-md": "var(--shadow-glass-md)",
259
+ "glass-lg": "var(--shadow-glass-lg)"
259
260
  },
260
261
  lineHeight: {
261
262
  none: "100%",
@@ -1,197 +0,0 @@
1
- import { useMemo as A, useState as I, useRef as W, useCallback as n } from "react";
2
- const T = (t, o = 2) => {
3
- if (t === 0) return "0 Bytes";
4
- const c = 1024, p = o < 0 ? 0 : o, a = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], v = Math.floor(Math.log(t) / Math.log(c));
5
- return Number.parseFloat((t / Math.pow(c, v)).toFixed(p)) + a[v];
6
- }, O = {
7
- fileTooLarge: (t, o) => `File "${t}" exceeds the maximum size of ${T(o)}.`,
8
- invalidFileType: (t) => `File "${t}" is not an accepted file type.`,
9
- tooManyFiles: (t) => `You can only upload a maximum of ${t} files.`,
10
- someFilesTooLarge: (t) => `Some files exceed the maximum size of ${T(t)}.`,
11
- singleFileTooLarge: (t) => `File exceeds the maximum size of ${T(t)}.`
12
- }, N = {
13
- fileTooLarge: (t, o) => `Файл "${t}" превышает максимальный размер ${T(o)}`,
14
- invalidFileType: (t) => `Файл "${t}" имеет недопустимый тип`,
15
- tooManyFiles: (t) => `Можно загрузить максимум ${t} файлов`,
16
- someFilesTooLarge: (t) => `Некоторые файлы превышают максимальный размер ${T(t)}`,
17
- singleFileTooLarge: (t) => `Файл превышает максимальный размер ${T(t)}`
18
- }, Y = (t = {}) => {
19
- const {
20
- maxFiles: o = 1 / 0,
21
- maxSize: c = 1 / 0,
22
- accept: p = "*",
23
- multiple: a = !1,
24
- initialFiles: v = [],
25
- onFilesChange: m,
26
- onFilesAdded: M,
27
- errorMessages: w
28
- } = t, d = A(() => ({ ...O, ...w }), [w]), [y, f] = I({
29
- files: v.map((e) => ({
30
- file: e,
31
- id: e.id,
32
- preview: e.url
33
- })),
34
- isDragging: !1,
35
- errors: []
36
- }), u = W(null), x = n(
37
- (e) => {
38
- const r = (e instanceof File, e.name);
39
- if (e.size > c)
40
- return d.fileTooLarge(r, c);
41
- if (p !== "*") {
42
- const i = p.split(",").map((g) => g.trim()), l = e instanceof File ? e.type || "" : e.type, s = `.${r.split(".").pop()}`;
43
- if (!i.some((g) => {
44
- if (g.startsWith("."))
45
- return s.toLowerCase() === g.toLowerCase();
46
- if (g.endsWith("/*")) {
47
- const L = g.split("/")[0];
48
- return l.startsWith(`${L}/`);
49
- }
50
- return l === g;
51
- }))
52
- return d.invalidFileType(r);
53
- }
54
- return null;
55
- },
56
- [p, c, d]
57
- ), B = n((e) => e instanceof File ? URL.createObjectURL(e) : e.url, []), R = n((e) => e instanceof File ? `${e.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}` : e.id, []), $ = n(() => {
58
- f((e) => {
59
- e.files.forEach((i) => {
60
- i.preview && i.file instanceof File && i.file.type.startsWith("image/") && URL.revokeObjectURL(i.preview);
61
- }), u.current && (u.current.value = "");
62
- const r = {
63
- ...e,
64
- files: [],
65
- errors: []
66
- };
67
- return m?.(r.files), r;
68
- });
69
- }, [m]), F = n(
70
- (e) => {
71
- if (!e || e.length === 0) return;
72
- const r = Array.from(e), i = [];
73
- if (f((s) => ({ ...s, errors: [] })), a || $(), a && o !== 1 / 0 && y.files.length + r.length > o) {
74
- i.push(d.tooManyFiles(o)), f((s) => ({ ...s, errors: i }));
75
- return;
76
- }
77
- const l = [];
78
- r.forEach((s) => {
79
- if (a && y.files.some(
80
- (L) => L.file.name === s.name && L.file.size === s.size
81
- ))
82
- return;
83
- if (s.size > c) {
84
- i.push(
85
- a ? d.someFilesTooLarge(c) : d.singleFileTooLarge(c)
86
- );
87
- return;
88
- }
89
- const h = x(s);
90
- h ? i.push(h) : l.push({
91
- file: s,
92
- id: R(s),
93
- preview: B(s)
94
- });
95
- }), l.length > 0 ? (M?.(l), f((s) => {
96
- const h = a ? [...s.files, ...l] : l;
97
- return m?.(h), {
98
- ...s,
99
- files: h,
100
- errors: i
101
- };
102
- })) : i.length > 0 && f((s) => ({
103
- ...s,
104
- errors: i
105
- })), u.current && (u.current.value = "");
106
- },
107
- [
108
- y.files,
109
- o,
110
- a,
111
- c,
112
- x,
113
- B,
114
- R,
115
- $,
116
- m,
117
- M,
118
- d
119
- ]
120
- ), z = n(
121
- (e) => {
122
- f((r) => {
123
- const i = r.files.find((s) => s.id === e);
124
- i && i.preview && i.file instanceof File && i.file.type.startsWith("image/") && URL.revokeObjectURL(i.preview);
125
- const l = r.files.filter((s) => s.id !== e);
126
- return m?.(l), {
127
- ...r,
128
- files: l,
129
- errors: []
130
- };
131
- });
132
- },
133
- [m]
134
- ), E = n(() => {
135
- f((e) => ({
136
- ...e,
137
- errors: []
138
- }));
139
- }, []), U = n((e) => {
140
- e.preventDefault(), e.stopPropagation(), f((r) => ({ ...r, isDragging: !0 }));
141
- }, []), P = n((e) => {
142
- e.preventDefault(), e.stopPropagation(), !e.currentTarget.contains(e.relatedTarget) && f((r) => ({ ...r, isDragging: !1 }));
143
- }, []), b = n((e) => {
144
- e.preventDefault(), e.stopPropagation();
145
- }, []), C = n(
146
- (e) => {
147
- if (e.preventDefault(), e.stopPropagation(), f((r) => ({ ...r, isDragging: !1 })), !u.current?.disabled && e.dataTransfer.files && e.dataTransfer.files.length > 0)
148
- if (a)
149
- F(e.dataTransfer.files);
150
- else {
151
- const r = e.dataTransfer.files[0];
152
- F([r]);
153
- }
154
- },
155
- [F, a]
156
- ), D = n(
157
- (e) => {
158
- e.target.files && e.target.files.length > 0 && F(e.target.files);
159
- },
160
- [F]
161
- ), S = n(() => {
162
- u.current && u.current.click();
163
- }, []), k = n(
164
- (e = {}) => ({
165
- ...e,
166
- type: "file",
167
- onChange: D,
168
- accept: e.accept || p,
169
- multiple: e.multiple !== void 0 ? e.multiple : a,
170
- ref: u
171
- }),
172
- [p, a, D]
173
- );
174
- return [
175
- y,
176
- {
177
- addFiles: F,
178
- removeFile: z,
179
- clearFiles: $,
180
- clearErrors: E,
181
- handleDragEnter: U,
182
- handleDragLeave: P,
183
- handleDragOver: b,
184
- handleDrop: C,
185
- handleFileChange: D,
186
- openFileDialog: S,
187
- getInputProps: k
188
- }
189
- ];
190
- };
191
- export {
192
- N as a,
193
- O as d,
194
- T as f,
195
- Y as u
196
- };
197
- //# sourceMappingURL=useFileUpload-iDag0iqM.js.map