@sqrzro/ui 4.0.0-alpha.7 → 4.0.0-alpha.71

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 (301) hide show
  1. package/dist/components/buttons/ActionButton/index.d.ts +8 -6
  2. package/dist/components/buttons/ActionButton/index.js +3 -27
  3. package/dist/components/buttons/Button/index.d.ts +7 -6
  4. package/dist/components/buttons/Button/index.js +9 -19
  5. package/dist/components/collections/Collection/index.d.ts +7 -3
  6. package/dist/components/collections/Collection/index.js +9 -7
  7. package/dist/components/collections/DataTable/index.d.ts +14 -0
  8. package/dist/components/collections/DataTable/index.js +14 -0
  9. package/dist/components/collections/DefinitionList/index.d.ts +13 -0
  10. package/dist/components/collections/DefinitionList/index.js +13 -0
  11. package/dist/components/collections/EmptyMessage/index.d.ts +1 -1
  12. package/dist/components/collections/EmptyMessage/index.js +6 -4
  13. package/dist/components/collections/EmptyMessageAction/index.d.ts +2 -2
  14. package/dist/components/collections/EmptyMessageAction/index.js +1 -1
  15. package/dist/components/collections/List/index.d.ts +6 -3
  16. package/dist/components/collections/List/index.js +2 -2
  17. package/dist/components/collections/ListClientComponent/index.d.ts +7 -4
  18. package/dist/components/collections/ListClientComponent/index.js +8 -5
  19. package/dist/components/collections/ListItem/index.d.ts +10 -3
  20. package/dist/components/collections/ListItem/index.js +15 -23
  21. package/dist/components/collections/ListItemMenu/index.d.ts +8 -0
  22. package/dist/components/collections/ListItemMenu/index.js +7 -0
  23. package/dist/components/collections/ListItemMeta/index.d.ts +6 -4
  24. package/dist/components/collections/ListItemMeta/index.js +13 -17
  25. package/dist/components/collections/ListItemSecondary/index.d.ts +5 -3
  26. package/dist/components/collections/ListItemSecondary/index.js +12 -8
  27. package/dist/components/collections/Pagination/index.d.ts +1 -1
  28. package/dist/components/collections/Pagination/index.js +6 -7
  29. package/dist/components/collections/PaginationLink/index.d.ts +9 -0
  30. package/dist/components/collections/PaginationLink/index.js +9 -0
  31. package/dist/components/collections/Table/index.d.ts +3 -4
  32. package/dist/components/collections/Table/index.js +2 -8
  33. package/dist/components/collections/TableClientComponent/index.d.ts +7 -6
  34. package/dist/components/collections/TableClientComponent/index.js +11 -26
  35. package/dist/components/collections/TableRow/index.d.ts +13 -0
  36. package/dist/components/collections/TableRow/index.js +15 -0
  37. package/dist/components/collections/interfaces.d.ts +41 -34
  38. package/dist/components/collections/lang.js +1 -1
  39. package/dist/components/collections/utility/is-paginated.d.ts +1 -1
  40. package/dist/components/collections/utility/is-right-aligned.d.ts +3 -0
  41. package/dist/components/collections/utility/is-right-aligned.js +11 -0
  42. package/dist/components/collections/utility/normalize-href.d.ts +2 -0
  43. package/dist/components/collections/utility/normalize-href.js +8 -0
  44. package/dist/components/collections/utility/render-cell.d.ts +5 -0
  45. package/dist/components/collections/utility/render-cell.js +33 -0
  46. package/dist/components/elements/Badge/index.d.ts +12 -0
  47. package/dist/components/elements/Badge/index.js +9 -0
  48. package/dist/components/elements/ContentLink/index.d.ts +4 -0
  49. package/dist/components/elements/ContentLink/index.js +7 -0
  50. package/dist/components/elements/InfoPanel/index.d.ts +13 -0
  51. package/dist/components/elements/InfoPanel/index.js +20 -0
  52. package/dist/components/{utility → elements}/Link/index.d.ts +3 -2
  53. package/dist/components/{utility → elements}/Link/index.js +10 -9
  54. package/dist/components/elements/Menu/index.d.ts +19 -0
  55. package/dist/components/elements/Menu/index.js +17 -0
  56. package/dist/components/elements/MenuItem/index.d.ts +9 -0
  57. package/dist/components/elements/MenuItem/index.js +14 -0
  58. package/dist/components/elements/Page/index.d.ts +19 -0
  59. package/dist/components/elements/Page/index.js +18 -0
  60. package/dist/components/elements/Reference/index.d.ts +9 -0
  61. package/dist/components/elements/Reference/index.js +16 -0
  62. package/dist/components/elements/Summary/index.d.ts +13 -0
  63. package/dist/components/elements/Summary/index.js +22 -0
  64. package/dist/components/errors/AppError/index.d.ts +19 -0
  65. package/dist/components/errors/AppError/index.js +9 -0
  66. package/dist/components/errors/AppForbiddenError/index.d.ts +7 -0
  67. package/dist/components/errors/AppForbiddenError/index.js +6 -0
  68. package/dist/components/errors/AppNotFoundError/index.d.ts +7 -0
  69. package/dist/components/errors/AppNotFoundError/index.js +6 -0
  70. package/dist/components/errors/AppServerError/index.d.ts +8 -0
  71. package/dist/components/errors/AppServerError/index.js +17 -0
  72. package/dist/components/index.d.ts +35 -6
  73. package/dist/components/index.js +17 -3
  74. package/dist/components/modals/ConfirmModal/index.d.ts +5 -3
  75. package/dist/components/modals/ConfirmModal/index.js +3 -3
  76. package/dist/components/modals/Modal/index.d.ts +4 -4
  77. package/dist/components/modals/Modal/index.js +3 -3
  78. package/dist/components/modals/ModalActions/index.d.ts +3 -3
  79. package/dist/components/modals/ModalActions/index.js +4 -3
  80. package/dist/components/utility/Action/index.d.ts +11 -0
  81. package/dist/components/utility/Action/index.js +48 -0
  82. package/dist/components/utility/ActionList/index.d.ts +5 -5
  83. package/dist/components/utility/ActionList/index.js +5 -3
  84. package/dist/components/utility/AppBody/index.d.ts +5 -0
  85. package/dist/components/utility/AppBody/index.js +9 -0
  86. package/dist/components/utility/Calendar/index.d.ts +32 -0
  87. package/dist/components/utility/Calendar/index.js +66 -0
  88. package/dist/components/utility/CalendarDay/index.d.ts +11 -0
  89. package/dist/components/utility/CalendarDay/index.js +22 -0
  90. package/dist/components/utility/Confirmable/index.d.ts +9 -0
  91. package/dist/components/utility/Confirmable/index.js +14 -0
  92. package/dist/components/utility/Container/index.d.ts +1 -1
  93. package/dist/components/utility/Container/index.js +2 -2
  94. package/dist/components/utility/Loader/index.d.ts +1 -1
  95. package/dist/components/utility/Loader/index.js +5 -4
  96. package/dist/components/utility/Popover/index.d.ts +1 -1
  97. package/dist/components/utility/Popover/index.js +5 -5
  98. package/dist/components/utility/Toast/index.d.ts +2 -2
  99. package/dist/components/utility/Toast/index.js +6 -4
  100. package/dist/components/utility/Toaster/index.js +5 -5
  101. package/dist/filters/components/FilterBar/index.d.ts +5 -2
  102. package/dist/filters/components/FilterBarClientComponent/index.d.ts +2 -4
  103. package/dist/filters/components/FilterBarClientComponent/index.js +3 -43
  104. package/dist/filters/components/FilterClearButton/index.d.ts +7 -2
  105. package/dist/filters/components/FilterClearButton/index.js +8 -4
  106. package/dist/filters/components/FilterControl/index.d.ts +1 -1
  107. package/dist/filters/components/FilterControl/index.js +11 -4
  108. package/dist/filters/components/FilterItem/index.d.ts +2 -1
  109. package/dist/filters/components/FilterItem/index.js +3 -7
  110. package/dist/filters/components/FilterPanel/index.d.ts +1 -1
  111. package/dist/filters/{utility/filter.d.ts → filter.d.ts} +1 -1
  112. package/dist/filters/{utility/filter.js → filter.js} +8 -8
  113. package/dist/filters/filters/BooleanFilter/index.js +1 -1
  114. package/dist/filters/filters/CalendarFilter/index.js +3 -2
  115. package/dist/filters/filters/DateFilter/index.d.ts +1 -1
  116. package/dist/filters/filters/DateFilter/index.js +9 -4
  117. package/dist/filters/filters/DropdownFilter/index.js +1 -1
  118. package/dist/filters/filters/Filter/index.d.ts +5 -4
  119. package/dist/filters/filters/Filter/index.js +7 -7
  120. package/dist/filters/filters/SearchFilter/index.d.ts +7 -2
  121. package/dist/filters/filters/SearchFilter/index.js +8 -8
  122. package/dist/filters/filters/interfaces.d.ts +0 -2
  123. package/dist/filters/index.d.ts +2 -1
  124. package/dist/filters/index.js +2 -1
  125. package/dist/filters/interfaces.d.ts +2 -2
  126. package/dist/filters/utility/render-value.js +5 -5
  127. package/dist/forms/components/Autocomplete/index.d.ts +2 -2
  128. package/dist/forms/components/Autocomplete/index.js +3 -3
  129. package/dist/forms/components/AutocompleteList/index.d.ts +7 -0
  130. package/dist/forms/components/AutocompleteList/index.js +15 -0
  131. package/dist/forms/components/BaseCalendarInput/index.d.ts +11 -0
  132. package/dist/forms/components/BaseCalendarInput/index.js +22 -0
  133. package/dist/forms/components/CSVInput/index.d.ts +11 -0
  134. package/dist/forms/components/CSVInput/index.js +32 -0
  135. package/dist/forms/components/CalendarInput/index.d.ts +6 -0
  136. package/dist/forms/components/CalendarInput/index.js +14 -0
  137. package/dist/forms/components/ColorInput/index.d.ts +16 -0
  138. package/dist/forms/components/ColorInput/index.js +14 -0
  139. package/dist/forms/components/Dropdown/index.d.ts +1 -1
  140. package/dist/forms/components/Dropdown/index.js +9 -8
  141. package/dist/forms/components/DropdownItem/index.d.ts +9 -0
  142. package/dist/forms/components/DropdownItem/index.js +9 -0
  143. package/dist/forms/components/DropdownList/index.d.ts +1 -1
  144. package/dist/forms/components/DropdownList/index.js +7 -11
  145. package/dist/forms/components/EditableForm/index.d.ts +3 -3
  146. package/dist/forms/components/EditableForm/index.js +9 -9
  147. package/dist/forms/components/EditableFormField/index.d.ts +1 -1
  148. package/dist/forms/components/EditableFormField/index.js +3 -3
  149. package/dist/forms/components/EditableFormFields/index.d.ts +12 -0
  150. package/dist/forms/components/EditableFormFields/index.js +44 -1
  151. package/dist/forms/components/Form/index.d.ts +4 -2
  152. package/dist/forms/components/Form/index.js +7 -6
  153. package/dist/forms/components/FormError/index.d.ts +2 -2
  154. package/dist/forms/components/FormError/index.js +7 -5
  155. package/dist/forms/components/FormField/index.d.ts +7 -5
  156. package/dist/forms/components/FormField/index.js +15 -7
  157. package/dist/forms/components/FormFields/index.d.ts +22 -2
  158. package/dist/forms/components/FormFields/index.js +44 -2
  159. package/dist/forms/components/FormLabel/index.d.ts +1 -1
  160. package/dist/forms/components/FormLabel/index.js +4 -3
  161. package/dist/forms/components/ImageInput/index.d.ts +17 -0
  162. package/dist/forms/components/ImageInput/index.js +46 -0
  163. package/dist/forms/components/ImageInputPanel/index.d.ts +10 -0
  164. package/dist/forms/components/ImageInputPanel/index.js +34 -0
  165. package/dist/forms/components/ModalForm/index.d.ts +3 -2
  166. package/dist/forms/components/ModalForm/index.js +5 -4
  167. package/dist/forms/components/NumberInput/index.d.ts +1 -1
  168. package/dist/forms/components/PasswordComplexity/index.d.ts +16 -0
  169. package/dist/forms/components/PasswordComplexity/index.js +14 -0
  170. package/dist/forms/components/PasswordComplexityItem/index.d.ts +8 -0
  171. package/dist/forms/components/PasswordComplexityItem/index.js +10 -0
  172. package/dist/forms/components/PasswordInput/index.d.ts +1 -1
  173. package/dist/forms/components/PasswordInput/index.js +6 -6
  174. package/dist/forms/components/PointsInput/index.d.ts +5 -0
  175. package/dist/forms/components/{MoneyInput → PointsInput}/index.js +3 -3
  176. package/dist/forms/components/RangeCalendarInput/index.d.ts +6 -0
  177. package/dist/forms/components/RangeCalendarInput/index.js +14 -0
  178. package/dist/forms/components/StaticTextInput/index.d.ts +2 -2
  179. package/dist/forms/components/StaticTextInput/index.js +6 -7
  180. package/dist/forms/components/Switch/index.d.ts +9 -3
  181. package/dist/forms/components/Switch/index.js +7 -5
  182. package/dist/forms/components/TextArea/index.d.ts +14 -0
  183. package/dist/forms/components/TextArea/index.js +15 -0
  184. package/dist/forms/components/TextInput/index.d.ts +1 -1
  185. package/dist/forms/components/TextInput/index.js +5 -4
  186. package/dist/forms/hooks/useAutocomplete.d.ts +8 -6
  187. package/dist/forms/hooks/useAutocomplete.js +4 -4
  188. package/dist/forms/hooks/useDropdown.d.ts +5 -7
  189. package/dist/forms/hooks/useDropdown.js +5 -5
  190. package/dist/forms/hooks/useEditableDropdown.d.ts +4 -0
  191. package/dist/forms/hooks/useEditableDropdown.js +6 -0
  192. package/dist/forms/hooks/useEditableForm.js +8 -1
  193. package/dist/forms/hooks/useForm.d.ts +7 -14
  194. package/dist/forms/hooks/useForm.js +25 -27
  195. package/dist/forms/hooks/useModalForm.d.ts +2 -2
  196. package/dist/forms/hooks/useModalForm.js +9 -2
  197. package/dist/forms/index.d.ts +22 -6
  198. package/dist/forms/index.js +9 -4
  199. package/dist/forms/interfaces.d.ts +8 -1
  200. package/dist/forms/utility/extract-input-props.js +1 -0
  201. package/dist/forms/utility/format-date-value.d.ts +2 -0
  202. package/dist/forms/utility/format-date-value.js +13 -0
  203. package/dist/forms/utility/format-file-size.d.ts +2 -0
  204. package/dist/forms/utility/format-file-size.js +11 -0
  205. package/dist/forms/utility/preprocess-image.d.ts +6 -0
  206. package/dist/forms/utility/preprocess-image.js +58 -0
  207. package/dist/hooks/index.d.ts +3 -0
  208. package/dist/hooks/index.js +3 -0
  209. package/dist/hooks/useConfirmable.d.ts +21 -0
  210. package/dist/hooks/useConfirmable.js +58 -0
  211. package/dist/hooks/useDownload.d.ts +2 -0
  212. package/dist/hooks/useDownload.js +18 -0
  213. package/dist/hooks/usePopover.d.ts +12 -0
  214. package/dist/hooks/usePopover.js +24 -0
  215. package/dist/hooks/useSelected.d.ts +12 -0
  216. package/dist/hooks/useSelected.js +35 -0
  217. package/dist/hooks/useServerAction.d.ts +10 -0
  218. package/dist/hooks/useServerAction.js +17 -0
  219. package/dist/hooks/useSuccess.d.ts +10 -0
  220. package/dist/hooks/useSuccess.js +22 -0
  221. package/dist/mail/Mail/index.d.ts +8 -0
  222. package/dist/mail/Mail/index.js +108 -0
  223. package/dist/mail/MailBlock/index.d.ts +5 -0
  224. package/dist/mail/MailBlock/index.js +5 -0
  225. package/dist/mail/MailButton/index.d.ts +8 -0
  226. package/dist/mail/MailButton/index.js +28 -0
  227. package/dist/mail/MailTable/index.d.ts +9 -0
  228. package/dist/mail/MailTable/index.js +7 -0
  229. package/dist/mail/index.d.ts +8 -0
  230. package/dist/mail/index.js +4 -0
  231. package/dist/mail/utility/convert-to-datauri.d.ts +2 -0
  232. package/dist/mail/utility/convert-to-datauri.js +37 -0
  233. package/dist/mail/utility/interfaces.d.ts +23 -0
  234. package/dist/mail/utility/mail-config.d.ts +4 -0
  235. package/dist/mail/utility/mail-config.js +42 -0
  236. package/dist/navigation/components/AppNavigation/index.d.ts +3 -1
  237. package/dist/navigation/components/AppNavigation/index.js +4 -4
  238. package/dist/navigation/components/AppNavigationItem/index.d.ts +5 -3
  239. package/dist/navigation/components/AppNavigationItem/index.js +16 -7
  240. package/dist/navigation/components/Tabs/index.js +1 -4
  241. package/dist/navigation/hooks/useNavigation.d.ts +3 -3
  242. package/dist/navigation/hooks/useNavigation.js +5 -5
  243. package/dist/styles/classnames/config.d.ts +93 -0
  244. package/dist/styles/classnames/config.js +1 -0
  245. package/dist/styles/classnames/interfaces.d.ts +56 -0
  246. package/dist/styles/classnames/interfaces.js +1 -0
  247. package/dist/styles/classnames/utility/apply-sizes.d.ts +3 -0
  248. package/dist/styles/classnames/utility/apply-sizes.js +21 -0
  249. package/dist/styles/classnames/utility/apply-variants.d.ts +3 -0
  250. package/dist/styles/classnames/utility/apply-variants.js +26 -0
  251. package/dist/styles/classnames/utility/is-classname-object.d.ts +3 -0
  252. package/dist/styles/classnames/utility/is-classname-object.js +7 -0
  253. package/dist/styles/classnames/utility/parse-classnames.d.ts +6 -0
  254. package/dist/styles/classnames/utility/parse-classnames.js +33 -0
  255. package/dist/styles/context.d.ts +28 -0
  256. package/dist/styles/context.js +19 -0
  257. package/dist/styles/icons/config.d.ts +28 -0
  258. package/dist/styles/icons/config.js +1 -0
  259. package/dist/styles/icons/interfaces.d.ts +4 -0
  260. package/dist/styles/icons/interfaces.js +1 -0
  261. package/dist/styles/index.d.ts +6 -2
  262. package/dist/styles/index.js +2 -1
  263. package/dist/styles/styles.css +60 -0
  264. package/dist/utility/compare-dates.d.ts +2 -0
  265. package/dist/utility/compare-dates.js +13 -0
  266. package/dist/utility/get-date-state.d.ts +8 -0
  267. package/dist/utility/get-date-state.js +63 -0
  268. package/dist/utility/get-days.d.ts +2 -0
  269. package/dist/utility/get-days.js +5 -0
  270. package/dist/utility/get-weeks.d.ts +2 -0
  271. package/dist/utility/get-weeks.js +31 -0
  272. package/dist/utility/index.d.ts +1 -1
  273. package/dist/utility/interfaces.d.ts +33 -17
  274. package/dist/utility/is-data-object-array.d.ts +3 -0
  275. package/dist/utility/is-data-object-array.js +5 -0
  276. package/dist/utility/is-data-object.d.ts +3 -0
  277. package/dist/utility/is-data-object.js +4 -0
  278. package/package.json +34 -22
  279. package/dist/components/buttons/ConfirmableButton/index.d.ts +0 -7
  280. package/dist/components/buttons/ConfirmableButton/index.js +0 -13
  281. package/dist/components/collections/utility/filter-columns.d.ts +0 -3
  282. package/dist/components/collections/utility/filter-columns.js +0 -8
  283. package/dist/components/collections/utility/get-selected-from-search-params.d.ts +0 -2
  284. package/dist/components/collections/utility/get-selected-from-search-params.js +0 -5
  285. package/dist/components/collections/utility/set-selected-to-search-params.d.ts +0 -2
  286. package/dist/components/collections/utility/set-selected-to-search-params.js +0 -4
  287. package/dist/components/utility/ClassNames/index.d.ts +0 -6
  288. package/dist/components/utility/ClassNames/index.js +0 -7
  289. package/dist/components/utility/Page/index.d.ts +0 -18
  290. package/dist/components/utility/Page/index.js +0 -34
  291. package/dist/components/utility/RootLayout/index.d.ts +0 -15
  292. package/dist/components/utility/RootLayout/index.js +0 -14
  293. package/dist/forms/components/MoneyInput/index.d.ts +0 -5
  294. package/dist/styles/config.d.ts +0 -64
  295. package/dist/styles/config.js +0 -43
  296. package/dist/styles/icons.d.ts +0 -15
  297. package/dist/styles/icons.js +0 -7
  298. package/dist/styles/interfaces.d.ts +0 -41
  299. /package/dist/{styles → mail/utility}/interfaces.js +0 -0
  300. /package/dist/styles/{tw.d.ts → classnames/utility/tw.d.ts} +0 -0
  301. /package/dist/styles/{tw.js → classnames/utility/tw.js} +0 -0
@@ -0,0 +1,15 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useClassNames } from '../../../styles/context';
4
+ import tw from '../../../styles/classnames/utility/tw';
5
+ function TextArea({ classNames, classNameProps, hasError, id, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, rows = 4, value, }) {
6
+ const componentClassNames = useClassNames('textArea', { props: classNameProps, states: { isError: hasError ?? false } }, classNames);
7
+ function handleChange(event) {
8
+ if (onChange) {
9
+ const target = { name, value: event.target.value };
10
+ onChange({ target });
11
+ }
12
+ }
13
+ return (_jsx("textarea", { "aria-invalid": hasError, "aria-labelledby": hasError ? `${id || name}_err` : undefined /* eslint-disable-line no-undefined */, className: tw('w-full focus-visible:outline-0', isDisabled ? 'pointer-events-none opacity-30' : null, componentClassNames?.root), disabled: isDisabled, id: id || name, name: name, onBlur: onBlur, onChange: handleChange, onFocus: onFocus, onKeyDown: onKeyDown, placeholder: placeholder, rows: rows, value: value || '' }));
14
+ }
15
+ export default TextArea;
@@ -1,5 +1,5 @@
1
1
  import type { InputProps } from '../../../forms/interfaces';
2
- import type { ClassNameProps, ErrorableClassName } from '../../../styles/interfaces';
2
+ import type { ClassNameProps, ErrorableClassName } from '../../../styles/classnames/interfaces';
3
3
  export interface TextInputClassNames {
4
4
  loading: string;
5
5
  prefix: ErrorableClassName;
@@ -1,6 +1,7 @@
1
+ 'use client';
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { getClassNames } from '../../../styles/config';
3
- import tw from '../../../styles/tw';
3
+ import { useClassNames } from '../../../styles/context';
4
+ import tw from '../../../styles/classnames/utility/tw';
4
5
  /**
5
6
  *
6
7
  * ## ClassNames
@@ -14,7 +15,7 @@ import tw from '../../../styles/tw';
14
15
  * button itself is handled by the `renderClear` prop. | `string` |
15
16
  */
16
17
  function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, prefix, ref, suffix, type, value, }) {
17
- const componentClassNames = classNames || getClassNames('textInput')?.(classNameProps);
18
+ const componentClassNames = useClassNames('textInput', { props: classNameProps, states: { isError: hasError ?? false } }, classNames);
18
19
  function handleChange(event) {
19
20
  if (onChange) {
20
21
  const target = { name, value: event.target.value };
@@ -25,6 +26,6 @@ function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, i
25
26
  ? `${id || name}_err`
26
27
  : undefined /* eslint-disable-line no-undefined */, autoComplete: isAutocomplete === false
27
28
  ? 'one-time-code'
28
- : undefined /* eslint-disable-line no-undefined */, className: tw('peer w-full focus-visible:outline-0', prefix ? 'border-l-0' : null, (!prefix && suffix) || value ? 'border-r-0' : null, componentClassNames?.root?.default, hasError ? componentClassNames?.root?.error : null), disabled: isDisabled, formNoValidate: true, id: id || name, name: name, onBlur: onBlur, onChange: handleChange, onFocus: onFocus, onKeyDown: onKeyDown, placeholder: placeholder, type: type, value: value || '' }), suffix ? _jsx("div", { children: suffix }) : null] }));
29
+ : undefined /* eslint-disable-line no-undefined */, className: tw('peer w-full focus-visible:outline-0', prefix ? 'border-l-0' : null, (!prefix && suffix) || value ? 'border-r-0' : null, componentClassNames?.root), disabled: isDisabled, formNoValidate: true, id: id || name, name: name, onBlur: onBlur, onChange: handleChange, onFocus: onFocus, onKeyDown: onKeyDown, placeholder: placeholder, type: type, value: value || '' }), suffix ? _jsx("div", { children: suffix }) : null] }));
29
30
  }
30
31
  export default TextInput;
@@ -1,8 +1,10 @@
1
- import { DropdownObject } from '../interfaces';
2
- import { AutocompleteFormFieldProps } from '../components/FormFields';
3
- interface UseAutocompleteArgs<T extends string> {
4
- searchFn: (search: string) => Promise<DropdownObject<T>[]>;
5
- selectFn: (id: T) => Promise<DropdownObject<T> | null>;
1
+ import type { AutocompleteFormFieldProps } from '../components/FormFields';
2
+ import type { DropdownObject } from '../interfaces';
3
+ export interface UseAutocompleteArgs<T extends string, U extends unknown[] = unknown[]> {
4
+ deps?: [...U];
5
+ searchFn: (search: string, ...deps: U) => Promise<DropdownObject<T>[]>;
6
+ selectFn: (id: T, ...deps: U) => Promise<DropdownObject<T> | null>;
6
7
  }
7
- declare function useAutocomplete<T extends string>(props: AutocompleteFormFieldProps<T>, { searchFn, selectFn }: UseAutocompleteArgs<T>): AutocompleteFormFieldProps<T>;
8
+ export type UseAutocompleteReturn<T extends string> = AutocompleteFormFieldProps<T>;
9
+ declare function useAutocomplete<T extends string, U extends unknown[] = unknown[]>(props: AutocompleteFormFieldProps<T>, { searchFn, selectFn, deps }: UseAutocompleteArgs<T, U>): UseAutocompleteReturn<T>;
8
10
  export default useAutocomplete;
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { useEffect, useState } from 'react';
3
- function useAutocomplete(props, { searchFn, selectFn }) {
3
+ function useAutocomplete(props, { searchFn, selectFn, deps }) {
4
4
  const [isLoading, setIsLoading] = useState(false);
5
5
  const [options, setOptions] = useState([]);
6
6
  const [selected, setSelected] = useState(null);
@@ -9,7 +9,7 @@ function useAutocomplete(props, { searchFn, selectFn }) {
9
9
  setSelected(null);
10
10
  return;
11
11
  }
12
- const response = await selectFn(value);
12
+ const response = await selectFn(value, ...(deps ?? []));
13
13
  setOptions([]);
14
14
  setSelected(response);
15
15
  }
@@ -19,13 +19,13 @@ function useAutocomplete(props, { searchFn, selectFn }) {
19
19
  return;
20
20
  }
21
21
  setIsLoading(true);
22
- const response = await searchFn(search);
22
+ const response = await searchFn(search, ...(deps ?? []));
23
23
  setOptions(response);
24
24
  setIsLoading(false);
25
25
  }
26
26
  useEffect(() => {
27
27
  void handleSelect(props.value);
28
- }, [props.value]);
28
+ }, [props.value, ...(deps ?? [])]);
29
29
  return { ...props, isLoading, onSearch: handleSearch, options, selected };
30
30
  }
31
31
  export default useAutocomplete;
@@ -1,10 +1,8 @@
1
1
  import { DropdownObject } from '../interfaces';
2
- interface UseDropdownArgs<T extends string> {
3
- deps?: unknown[];
4
- fn: (...args: unknown[]) => Promise<DropdownObject<T>[]>;
2
+ import { DropdownFormFieldProps } from '../components/FormFields';
3
+ export interface UseDropdownArgs<T extends string, U extends unknown[] = unknown[]> {
4
+ deps?: [...U];
5
+ fn: (...deps: U) => Promise<DropdownObject<T>[]>;
5
6
  }
6
- interface UseDropdownReturn<T extends string> {
7
- data: DropdownObject<T>[];
8
- }
9
- declare function useDropdown<T extends string>({ deps, fn }: UseDropdownArgs<T>): UseDropdownReturn<T>;
7
+ declare function useDropdown<T extends string, U extends unknown[] = unknown[], TProps = DropdownFormFieldProps<T>>(props: TProps, { deps, fn }: UseDropdownArgs<T, U>): TProps;
10
8
  export default useDropdown;
@@ -1,14 +1,14 @@
1
1
  'use client';
2
2
  import { useEffect, useState } from 'react';
3
- function useDropdown({ deps, fn }) {
4
- const [data, setData] = useState([]);
3
+ function useDropdown(props, { deps, fn }) {
4
+ const [options, setOptions] = useState([]);
5
5
  async function getData() {
6
- const response = await (deps ? fn(...deps) : fn());
7
- setData(response);
6
+ const response = await fn(...(deps ?? []));
7
+ setOptions(response);
8
8
  }
9
9
  useEffect(() => {
10
10
  void getData();
11
11
  }, deps || []);
12
- return { data };
12
+ return { ...props, options };
13
13
  }
14
14
  export default useDropdown;
@@ -0,0 +1,4 @@
1
+ import { EditableDropdownFormFieldProps } from '../components/EditableFormFields';
2
+ import { UseDropdownArgs } from './useDropdown';
3
+ declare function useEditableDropdown<T extends string, U extends unknown[] = unknown[]>(props: EditableDropdownFormFieldProps<T>, args: UseDropdownArgs<T, U>): EditableDropdownFormFieldProps<T>;
4
+ export default useEditableDropdown;
@@ -0,0 +1,6 @@
1
+ 'use client';
2
+ import useDropdown from './useDropdown';
3
+ function useEditableDropdown(props, args) {
4
+ return useDropdown(props, args);
5
+ }
6
+ export default useEditableDropdown;
@@ -26,7 +26,14 @@ function useEditableForm({ defaultStatus, onCancel, onEdit, onSuccess, title, ..
26
26
  ...useFormReturn,
27
27
  actionProps: { status, setStatus },
28
28
  fieldProps: editableFieldProps,
29
- formProps: { formProps: useFormReturn.formProps, onCancel, onEdit, status, setStatus, title },
29
+ formProps: {
30
+ formProps: useFormReturn.formProps,
31
+ onCancel,
32
+ onEdit,
33
+ status,
34
+ setStatus,
35
+ title,
36
+ },
30
37
  status,
31
38
  setStatus,
32
39
  };
@@ -1,17 +1,12 @@
1
- import type { Default, InputEvent } from '../../forms/interfaces';
1
+ import type { Default, FormResponse, InputEvent } from '../../forms/interfaces';
2
+ import type { UseSuccessArgs } from '../../hooks/useSuccess';
2
3
  import type { FormProps } from '../components/Form';
3
- interface AwaitedFormResponse<M> {
4
- data: M | null;
5
- error: string | null;
6
- validation: Record<string, string> | null;
7
- }
8
- export type FormResponse<M> = Promise<AwaitedFormResponse<M>>;
9
4
  export interface FieldPropsReturn<Request, K extends keyof Request = keyof Request> {
10
5
  error: Record<string, string> | null;
11
6
  isDisabled?: boolean;
12
7
  label?: string;
13
8
  name: string;
14
- onChange: (event: InputEvent<Request[K]>) => void;
9
+ onFieldChange: (event: InputEvent<Request[K]>) => void;
15
10
  value: Request[K];
16
11
  }
17
12
  export interface ToastsArgs {
@@ -19,14 +14,11 @@ export interface ToastsArgs {
19
14
  success?: string | false;
20
15
  validation?: string | false;
21
16
  }
22
- export interface UseFormArgs<Request, Response> {
17
+ export interface UseFormArgs<Request, Response> extends UseSuccessArgs<Response> {
23
18
  defaults?: Default<Request>;
24
19
  onError?: (message: string) => void;
25
20
  onSubmit?: (formData: Request) => FormResponse<Response>;
26
- onSuccess?: (response: Response) => Promise<void> | void;
27
- onValidation?: (errors: Record<string, string>) => void;
28
- redirectOnSuccess?: string | false | ((response: Response) => string | false);
29
- refreshOnSuccess?: boolean;
21
+ onValidation?: (errors: Record<string, string>, uncaughtErrors?: Record<string, string>) => void;
30
22
  toasts?: ToastsArgs | false;
31
23
  }
32
24
  export interface UseFormReturn<Request> {
@@ -37,9 +29,10 @@ export interface UseFormReturn<Request> {
37
29
  isLoading: boolean;
38
30
  resetForm: () => void;
39
31
  setErrors: (errors: Record<string, string> | null) => void;
40
- setFormData: (key: keyof Request, value: Request[keyof Request]) => void;
32
+ setFormData: <K extends keyof Request>(key: K, value: Request[K]) => void;
41
33
  submitForm: () => void;
42
34
  }
35
+ export declare const DEFAULT_TOAST_MESSAGES: Record<keyof ToastsArgs, string>;
43
36
  /**
44
37
  * ## Overview
45
38
  *
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
  import { useRef, useState, useTransition } from 'react';
3
3
  import { formatTitle } from '@sqrzro/utility';
4
- import { useRouter } from 'next/navigation';
5
4
  import useDeepCompareEffect from 'use-deep-compare-effect';
5
+ import useSuccess from '../../hooks/useSuccess';
6
6
  import useToast from '../../hooks/useToast';
7
- const DEFAULT_TOAST_MESSAGES = {
7
+ export const DEFAULT_TOAST_MESSAGES = {
8
8
  server: 'There was a problem submitting your request. Please try again later.',
9
9
  success: 'Your request was submitted successfully.',
10
10
  validation: 'There was a problem with your submission. Please check the form and try again.',
@@ -120,10 +120,12 @@ function getToastMessage(key, toasts) {
120
120
  * handling additional form events or integrating with different server APIs.
121
121
  */
122
122
  function useForm({ defaults = {}, onError, onSubmit, onSuccess, onValidation, redirectOnSuccess, refreshOnSuccess, toasts, }) {
123
- const innerRef = useRef(null);
124
- const router = useRouter();
125
- const [isLoading, startTransition] = useTransition();
123
+ const ref = useRef(null);
124
+ const usedFields = useRef(new Set());
125
+ const { handleSuccess } = useSuccess({ onSuccess, redirectOnSuccess, refreshOnSuccess });
126
+ const [isLoading] = useTransition();
126
127
  const [errors, setErrors] = useState(null);
128
+ const [uncaughtErrors, setUncaughtErrors] = useState(null);
127
129
  const [data, setData] = useState(defaults);
128
130
  const { toastError, toastSuccess } = useToast();
129
131
  function setFormData(key, value) {
@@ -132,28 +134,21 @@ function useForm({ defaults = {}, onError, onSubmit, onSuccess, onValidation, re
132
134
  function handleChange(event) {
133
135
  setData((prev) => ({ ...prev, [event.target.name]: event.target.value }));
134
136
  }
135
- async function handleSuccess(response) {
136
- await onSuccess?.(response);
137
- if (redirectOnSuccess) {
138
- const redirect = typeof redirectOnSuccess === 'function'
139
- ? redirectOnSuccess(response)
140
- : redirectOnSuccess;
141
- if (redirect) {
142
- router.push(redirect);
143
- }
144
- }
145
- if (refreshOnSuccess) {
146
- router.refresh();
147
- }
137
+ async function handleFormSuccess(response) {
138
+ await handleSuccess(response);
148
139
  toastSuccess(getToastMessage('success', toasts));
149
140
  }
150
- function handleError(message) {
141
+ function handleFormError(message) {
151
142
  onError?.(message);
152
143
  toastError(getToastMessage('server', toasts));
153
144
  }
154
- function handleValidation(messages) {
155
- onValidation?.(messages);
145
+ function handleFormValidation(messages) {
146
+ const uncaughtMessages = Object.keys(messages)
147
+ .filter((key) => !usedFields.current.has(key))
148
+ .reduce((acc, key) => ({ ...acc, [key]: messages[key] }), {});
149
+ onValidation?.(messages, uncaughtMessages);
156
150
  setErrors(messages);
151
+ setUncaughtErrors(uncaughtMessages);
157
152
  toastError(getToastMessage('validation', toasts));
158
153
  }
159
154
  async function handleSubmit() {
@@ -163,21 +158,22 @@ function useForm({ defaults = {}, onError, onSubmit, onSuccess, onValidation, re
163
158
  setErrors(null);
164
159
  const fnReturn = await onSubmit(data);
165
160
  if (fnReturn.error) {
166
- return handleError(fnReturn.error);
161
+ return handleFormError(fnReturn.error);
167
162
  }
168
163
  if (fnReturn.validation) {
169
- return handleValidation(fnReturn.validation);
164
+ return handleFormValidation(fnReturn.validation);
170
165
  }
171
- if (fnReturn.data) {
172
- return handleSuccess(fnReturn.data);
166
+ if (fnReturn.data !== null) {
167
+ return handleFormSuccess(fnReturn.data);
173
168
  }
174
169
  }
175
170
  function fieldProps(name, label) {
171
+ usedFields.current.add(name);
176
172
  return {
177
173
  error: getErrorsForField(errors, name),
178
174
  label: getLabel(name, label),
179
175
  name: name,
180
- onChange: handleChange,
176
+ onFieldChange: handleChange,
181
177
  value: data[name],
182
178
  };
183
179
  }
@@ -196,13 +192,15 @@ function useForm({ defaults = {}, onError, onSubmit, onSuccess, onValidation, re
196
192
  formData: data,
197
193
  formProps: {
198
194
  action: handleSubmit,
195
+ ref,
196
+ uncaughtErrors,
199
197
  },
200
198
  isLoading,
201
199
  resetForm,
202
200
  setErrors,
203
201
  setFormData,
204
202
  submitForm: () => {
205
- setTimeout(() => innerRef.current?.requestSubmit(), 1);
203
+ setTimeout(() => ref.current?.requestSubmit(), 1);
206
204
  },
207
205
  };
208
206
  }
@@ -1,8 +1,8 @@
1
- import type { Action } from '../../utility/interfaces';
1
+ import type { SimpleActionObject } from '../../utility/interfaces';
2
2
  import type { ModalFormProps } from '../components/ModalForm';
3
3
  import type { UseFormArgs, UseFormReturn } from './useForm';
4
4
  export interface UseModalFormArgs<Request, Response> extends UseFormArgs<Request, Response> {
5
- actions?: Action[];
5
+ actions?: SimpleActionObject[];
6
6
  icon?: React.ReactNode;
7
7
  submitLabel?: string;
8
8
  title?: string;
@@ -1,19 +1,25 @@
1
1
  'use client';
2
+ import { useState } from 'react';
2
3
  import { useRouter } from 'next/navigation';
3
4
  import useSearchParamsHref from '../../hooks/useSearchParamsHref';
4
- import useForm from './useForm';
5
+ import useForm, { DEFAULT_TOAST_MESSAGES } from './useForm';
5
6
  function useModalForm({ actions, icon, submitLabel, title, ...useFormArgs }) {
7
+ const [serverError, setServerError] = useState(null);
6
8
  const { setSearchParamsHref } = useSearchParamsHref();
7
9
  const router = useRouter();
8
10
  function handleSuccess(response) {
9
11
  useFormArgs.onSuccess?.(response);
10
- setSearchParamsHref('action', null);
12
+ setSearchParamsHref({ action: null, id: null });
11
13
  setTimeout(() => {
12
14
  router.refresh();
13
15
  }, 1);
14
16
  }
15
17
  const useFormReturn = useForm({
16
18
  ...useFormArgs,
19
+ onError: (message) => {
20
+ setServerError(DEFAULT_TOAST_MESSAGES.server);
21
+ useFormArgs.onError?.(message);
22
+ },
17
23
  onSuccess: handleSuccess,
18
24
  toasts: false,
19
25
  });
@@ -22,6 +28,7 @@ function useModalForm({ actions, icon, submitLabel, title, ...useFormArgs }) {
22
28
  formProps: {
23
29
  formProps: useFormReturn.formProps,
24
30
  modalProps: { actions, icon, title },
31
+ serverError,
25
32
  submitLabel,
26
33
  },
27
34
  };
@@ -1,6 +1,8 @@
1
1
  export * from './interfaces';
2
2
  export type { AutocompleteProps } from './components/Autocomplete';
3
3
  export { default as Autocomplete } from './components/Autocomplete';
4
+ export type { CSVInputClassNames, CSVInputProps } from './components/CSVInput';
5
+ export { default as CSVInput } from './components/CSVInput';
4
6
  export type { DropdownClassNames, DropdownProps } from './components/Dropdown';
5
7
  export { default as Dropdown } from './components/Dropdown';
6
8
  export type { EditableFormClassNames, EditableFormProps } from './components/EditableForm';
@@ -9,26 +11,40 @@ export type { EditableFormFieldProps } from './components/EditableFormField';
9
11
  export { default as EditableFormField } from './components/EditableFormField';
10
12
  export type { FormClassNames, FormProps } from './components/Form';
11
13
  export { default as Form } from './components/Form';
14
+ export type { FormErrorProps } from './components/FormError';
15
+ export { default as FormError } from './components/FormError';
12
16
  export type { FormFieldClassNames, FormFieldProps } from './components/FormField';
13
17
  export { default as FormField } from './components/FormField';
14
18
  export type { FormSubmitProps } from './components/FormSubmit';
15
19
  export { default as FormSubmit } from './components/FormSubmit';
16
20
  export type { ModalFormProps } from './components/ModalForm';
17
21
  export { default as ModalForm } from './components/ModalForm';
18
- export type { MoneyInputProps } from './components/MoneyInput';
19
- export { default as MoneyInput } from './components/MoneyInput';
22
+ export type { PasswordComplexityProps } from './components/PasswordComplexity';
23
+ export { default as PasswordComplexity } from './components/PasswordComplexity';
20
24
  export type { NumberInputProps } from './components/NumberInput';
21
25
  export { default as NumberInput } from './components/NumberInput';
22
26
  export type { PasswordInputClassNames, PasswordInputProps } from './components/PasswordInput';
23
27
  export { default as PasswordInput } from './components/PasswordInput';
28
+ export type { PointsInputProps } from './components/PointsInput';
29
+ export { default as PointsInput } from './components/PointsInput';
30
+ export type { StaticTextInputClassNames, StaticTextInputProps } from './components/StaticTextInput';
31
+ export { default as StaticTextInput } from './components/StaticTextInput';
32
+ export type { TextAreaClassNames, TextAreaProps } from './components/TextArea';
33
+ export { default as TextArea } from './components/TextArea';
24
34
  export type { TextInputClassNames, TextInputProps } from './components/TextInput';
25
35
  export { default as TextInput } from './components/TextInput';
26
- export type { EditableDropdownFormFieldProps, EditableTextFormFieldProps, } from './components/EditableFormFields';
27
- export { EditableDropdownFormField, EditableTextFormField } from './components/EditableFormFields';
28
- export type { AutocompleteFormFieldProps, DropdownFormFieldProps, MoneyFormFieldProps, NumberFormFieldProps, PasswordFormFieldProps, TextFormFieldProps, } from './components/FormFields';
29
- export { AutocompleteFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
36
+ export type * from './components/EditableFormFields';
37
+ export * from './components/EditableFormFields';
38
+ export type * from './components/FormFields';
39
+ export * from './components/FormFields';
40
+ export type { UseAutocompleteArgs, UseAutocompleteReturn } from './hooks/useAutocomplete';
30
41
  export { default as useAutocomplete } from './hooks/useAutocomplete';
42
+ export type { UseDropdownArgs } from './hooks/useDropdown';
31
43
  export { default as useDropdown } from './hooks/useDropdown';
44
+ export { default as useEditableDropdown } from './hooks/useEditableDropdown';
45
+ export type { UseEditableFormArgs, UseEditableFormReturn } from './hooks/useEditableForm';
32
46
  export { default as useEditableForm } from './hooks/useEditableForm';
47
+ export type { UseFormArgs, UseFormReturn } from './hooks/useForm';
33
48
  export { default as useForm } from './hooks/useForm';
49
+ export type { UseModalFormArgs, UseModalFormReturn } from './hooks/useModalForm';
34
50
  export { default as useModalForm } from './hooks/useModalForm';
@@ -1,21 +1,26 @@
1
1
  export * from './interfaces';
2
2
  export { default as Autocomplete } from './components/Autocomplete';
3
+ export { default as CSVInput } from './components/CSVInput';
3
4
  export { default as Dropdown } from './components/Dropdown';
4
5
  export { default as EditableForm } from './components/EditableForm';
5
6
  export { default as EditableFormField } from './components/EditableFormField';
6
7
  export { default as Form } from './components/Form';
8
+ export { default as FormError } from './components/FormError';
7
9
  export { default as FormField } from './components/FormField';
8
10
  export { default as FormSubmit } from './components/FormSubmit';
9
11
  export { default as ModalForm } from './components/ModalForm';
10
- export { default as MoneyInput } from './components/MoneyInput';
12
+ export { default as PasswordComplexity } from './components/PasswordComplexity';
11
13
  export { default as NumberInput } from './components/NumberInput';
12
14
  export { default as PasswordInput } from './components/PasswordInput';
15
+ export { default as PointsInput } from './components/PointsInput';
16
+ export { default as StaticTextInput } from './components/StaticTextInput';
17
+ export { default as TextArea } from './components/TextArea';
13
18
  export { default as TextInput } from './components/TextInput';
14
- export { EditableDropdownFormField, EditableTextFormField } from './components/EditableFormFields';
15
- export { AutocompleteFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
16
- // Hooks
19
+ export * from './components/EditableFormFields';
20
+ export * from './components/FormFields';
17
21
  export { default as useAutocomplete } from './hooks/useAutocomplete';
18
22
  export { default as useDropdown } from './hooks/useDropdown';
23
+ export { default as useEditableDropdown } from './hooks/useEditableDropdown';
19
24
  export { default as useEditableForm } from './hooks/useEditableForm';
20
25
  export { default as useForm } from './hooks/useForm';
21
26
  export { default as useModalForm } from './hooks/useModalForm';
@@ -1,5 +1,11 @@
1
1
  import type { EditableFormFieldProps } from './components/EditableFormField';
2
2
  import type { FormFieldProps } from './components/FormField';
3
+ export interface AwaitedFormResponse<M> {
4
+ data: M | null;
5
+ error: string | null;
6
+ validation: Record<string, string> | null;
7
+ }
8
+ export type FormResponse<M> = Promise<AwaitedFormResponse<M>>;
3
9
  export type Default<T> = {
4
10
  [K in keyof T]?: T[K] | null;
5
11
  };
@@ -7,7 +13,7 @@ export interface DropdownObject<T = string> {
7
13
  $data?: Record<string, string>;
8
14
  details?: string | null;
9
15
  isDisabled?: boolean;
10
- label: string;
16
+ label: React.ReactNode;
11
17
  value: T;
12
18
  }
13
19
  export type EditingStatus = 'CANCELLED' | 'EDITING' | 'SAVED';
@@ -28,6 +34,7 @@ export interface InputProps<V, T extends V = V> {
28
34
  name: string;
29
35
  ref?: React.Ref<HTMLInputElement>;
30
36
  onChange?: (event: InputEvent<T>) => void;
37
+ onError?: (error: string) => void;
31
38
  onKeyDown?: React.KeyboardEventHandler;
32
39
  value?: V;
33
40
  }
@@ -13,6 +13,7 @@ export function getFieldPropKeys() {
13
13
  'label',
14
14
  'name',
15
15
  'onChange',
16
+ 'onFieldChange',
16
17
  'onKeyDown',
17
18
  'value',
18
19
  ];
@@ -0,0 +1,2 @@
1
+ declare function formatDateValue(date?: Date | [Date, Date] | null): string | null;
2
+ export default formatDateValue;
@@ -0,0 +1,13 @@
1
+ import { formatDate } from '@sqrzro/utility';
2
+ function formatDateValue(date) {
3
+ if (!date) {
4
+ return null;
5
+ }
6
+ const dateArray = Array.isArray(date) ? date : [date];
7
+ const formattedArray = dateArray.map((item) => formatDate(item));
8
+ if (formattedArray[0] === formattedArray[1]) {
9
+ return formattedArray[0];
10
+ }
11
+ return formattedArray.join(' - ');
12
+ }
13
+ export default formatDateValue;
@@ -0,0 +1,2 @@
1
+ declare function formatFileSize(size: number): string;
2
+ export default formatFileSize;
@@ -0,0 +1,11 @@
1
+ const BYTES_IN_KB = 1024;
2
+ const DECIMAL_PLACES = 3;
3
+ function formatFileSize(size) {
4
+ const units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
5
+ const exponent = Math.min(Math.floor(Math.log(size) / Math.log(BYTES_IN_KB)), units.length - 1);
6
+ const approx = size / BYTES_IN_KB ** exponent;
7
+ return exponent === 0
8
+ ? `${size} bytes`
9
+ : `${approx.toFixed(DECIMAL_PLACES)} ${units[exponent]} (${size} bytes)`;
10
+ }
11
+ export default formatFileSize;
@@ -0,0 +1,6 @@
1
+ interface PreprocessImageOptions {
2
+ maxSize?: [number?, number?];
3
+ minSize?: [number?, number?];
4
+ }
5
+ export declare function preprocessImage(file: File, options?: PreprocessImageOptions): Promise<File>;
6
+ export default preprocessImage;
@@ -0,0 +1,58 @@
1
+ const ALLOWED_TYPES = [
2
+ 'image/jpeg',
3
+ 'image/png',
4
+ 'image/gif',
5
+ 'image/svg+xml',
6
+ 'image/webp',
7
+ ];
8
+ function isSupportedImage(file) {
9
+ return ALLOWED_TYPES.includes(file.type);
10
+ }
11
+ function fitWithinMaxSize(width, height, maxWidth, maxHeight) {
12
+ const scale = Math.min(maxWidth / width, maxHeight / height, 1);
13
+ return [Math.round(width * scale), Math.round(height * scale)];
14
+ }
15
+ export async function preprocessImage(file, options = {}) {
16
+ if (!isSupportedImage(file)) {
17
+ throw new Error('Unsupported file type');
18
+ }
19
+ if (file.type === 'image/svg+xml') {
20
+ return file;
21
+ }
22
+ const bitmap = await createImageBitmap(file);
23
+ const { maxSize, minSize } = options;
24
+ const maxWidth = maxSize?.[0] || 1000;
25
+ const maxHeight = maxSize?.[1] || 1000;
26
+ const minWidth = minSize?.[0] || 0;
27
+ const minHeight = minSize?.[1] || 0;
28
+ let { width, height } = bitmap;
29
+ if (width < minWidth || height < minHeight) {
30
+ throw new Error(`Image is smaller than the minimum size`);
31
+ }
32
+ const [newWidth, newHeight] = fitWithinMaxSize(width, height, maxWidth, maxHeight);
33
+ const canvas = document.createElement('canvas');
34
+ canvas.width = newWidth;
35
+ canvas.height = newHeight;
36
+ const ctx = canvas.getContext('2d');
37
+ if (!ctx) {
38
+ throw new Error('Could not get canvas context');
39
+ }
40
+ ctx.drawImage(bitmap, 0, 0, newWidth, newHeight);
41
+ const blob = await new Promise((resolve, reject) => {
42
+ canvas.toBlob((data) => {
43
+ if (data) {
44
+ resolve(data);
45
+ }
46
+ else {
47
+ reject(new Error('Failed to create WebP blob'));
48
+ }
49
+ }, 'image/webp', 1);
50
+ });
51
+ const baseName = file.name.replace(/\.\w+$/, '');
52
+ const newName = `${baseName}.webp`;
53
+ return new File([blob], newName, {
54
+ type: 'image/webp',
55
+ lastModified: Date.now(),
56
+ });
57
+ }
58
+ export default preprocessImage;
@@ -1 +1,4 @@
1
1
  export { default as useClickOutside } from './useClickOutside';
2
+ export { default as useDownload } from './useDownload';
3
+ export { default as usePopover } from './usePopover';
4
+ export { default as useServerAction } from './useServerAction';
@@ -1 +1,4 @@
1
1
  export { default as useClickOutside } from './useClickOutside';
2
+ export { default as useDownload } from './useDownload';
3
+ export { default as usePopover } from './usePopover';
4
+ export { default as useServerAction } from './useServerAction';