@sqrzro/ui 4.0.0-alpha.0 → 4.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/dist/components/buttons/ActionButton/index.d.ts +7 -0
  2. package/dist/components/buttons/ActionButton/index.js +33 -0
  3. package/dist/components/buttons/Button/index.d.ts +65 -0
  4. package/dist/components/buttons/Button/index.js +50 -0
  5. package/dist/components/buttons/ConfirmableButton/index.d.ts +7 -0
  6. package/dist/components/buttons/ConfirmableButton/index.js +13 -0
  7. package/dist/components/buttons/TextButton/index.d.ts +5 -0
  8. package/dist/components/buttons/TextButton/index.js +6 -0
  9. package/dist/components/collections/Collection/index.d.ts +15 -0
  10. package/dist/components/collections/Collection/index.js +45 -0
  11. package/dist/components/collections/EmptyMessage/index.d.ts +26 -0
  12. package/dist/components/collections/EmptyMessage/index.js +17 -0
  13. package/dist/components/collections/EmptyMessageAction/index.d.ts +6 -0
  14. package/dist/components/collections/EmptyMessageAction/index.js +19 -0
  15. package/dist/components/collections/List/index.d.ts +6 -0
  16. package/dist/components/collections/List/index.js +13 -0
  17. package/dist/components/collections/ListClientComponent/index.d.ts +7 -0
  18. package/dist/components/collections/ListClientComponent/index.js +9 -0
  19. package/dist/components/collections/ListItem/index.d.ts +14 -0
  20. package/dist/components/collections/ListItem/index.js +28 -0
  21. package/dist/components/collections/ListItemMeta/index.d.ts +11 -0
  22. package/dist/components/collections/ListItemMeta/index.js +22 -0
  23. package/dist/components/collections/ListItemSecondary/index.d.ts +6 -0
  24. package/dist/components/collections/ListItemSecondary/index.js +16 -0
  25. package/dist/components/collections/Pagination/index.d.ts +19 -0
  26. package/dist/components/collections/Pagination/index.js +17 -0
  27. package/dist/components/collections/Table/index.d.ts +9 -0
  28. package/dist/components/collections/Table/index.js +13 -0
  29. package/dist/components/collections/TableClientComponent/index.d.ts +14 -0
  30. package/dist/components/collections/TableClientComponent/index.js +30 -0
  31. package/dist/components/collections/interfaces.d.ts +57 -0
  32. package/dist/components/collections/interfaces.js +1 -0
  33. package/dist/components/collections/lang.d.ts +4 -0
  34. package/dist/components/collections/lang.js +4 -0
  35. package/dist/components/collections/utility/filter-columns.d.ts +3 -0
  36. package/dist/components/collections/utility/filter-columns.js +8 -0
  37. package/dist/components/collections/utility/get-selected-from-search-params.d.ts +2 -0
  38. package/dist/components/collections/utility/get-selected-from-search-params.js +5 -0
  39. package/dist/components/collections/utility/is-paginated.d.ts +3 -0
  40. package/dist/components/collections/utility/is-paginated.js +4 -0
  41. package/dist/components/collections/utility/set-selected-to-search-params.d.ts +2 -0
  42. package/dist/components/collections/utility/set-selected-to-search-params.js +4 -0
  43. package/dist/components/index.d.ts +16 -0
  44. package/dist/components/index.js +9 -0
  45. package/dist/components/modals/ConfirmModal/index.d.ts +7 -0
  46. package/dist/components/modals/ConfirmModal/index.js +23 -0
  47. package/dist/components/modals/Modal/index.d.ts +19 -0
  48. package/dist/components/modals/Modal/index.js +17 -0
  49. package/dist/components/modals/ModalActions/index.d.ts +9 -0
  50. package/dist/components/modals/ModalActions/index.js +8 -0
  51. package/dist/components/modals/ModalLauncher/index.d.ts +5 -0
  52. package/dist/components/modals/ModalLauncher/index.js +14 -0
  53. package/dist/components/utility/ActionList/index.d.ts +12 -0
  54. package/dist/components/utility/ActionList/index.js +9 -0
  55. package/dist/components/utility/Assistive/index.d.ts +8 -0
  56. package/dist/components/utility/Assistive/index.js +8 -0
  57. package/dist/components/utility/ClassNames/index.d.ts +6 -0
  58. package/dist/components/utility/ClassNames/index.js +7 -0
  59. package/dist/components/utility/Container/index.d.ts +9 -0
  60. package/dist/components/utility/Container/index.js +8 -0
  61. package/dist/components/utility/Link/index.d.ts +19 -0
  62. package/dist/components/utility/Link/index.js +33 -0
  63. package/dist/components/utility/Loader/index.d.ts +8 -0
  64. package/dist/components/utility/Loader/index.js +9 -0
  65. package/dist/components/utility/Page/index.d.ts +18 -0
  66. package/dist/components/utility/Page/index.js +34 -0
  67. package/dist/components/utility/Popover/index.d.ts +14 -0
  68. package/dist/components/utility/Popover/index.js +71 -0
  69. package/dist/components/utility/RootLayout/index.d.ts +12 -0
  70. package/dist/components/utility/RootLayout/index.js +14 -0
  71. package/dist/components/utility/Toast/index.d.ts +11 -0
  72. package/dist/components/utility/Toast/index.js +11 -0
  73. package/dist/components/utility/Toaster/index.d.ts +8 -0
  74. package/dist/components/utility/Toaster/index.js +57 -0
  75. package/dist/filters/components/FilterBar/index.d.ts +9 -0
  76. package/dist/filters/components/FilterBar/index.js +9 -0
  77. package/dist/filters/components/FilterBarClientComponent/index.d.ts +12 -0
  78. package/dist/filters/components/FilterBarClientComponent/index.js +68 -0
  79. package/dist/filters/components/FilterClearButton/index.d.ts +5 -0
  80. package/dist/filters/components/FilterClearButton/index.js +6 -0
  81. package/dist/filters/components/FilterControl/index.d.ts +12 -0
  82. package/dist/filters/components/FilterControl/index.js +10 -0
  83. package/dist/filters/components/FilterItem/index.d.ts +14 -0
  84. package/dist/filters/components/FilterItem/index.js +43 -0
  85. package/dist/filters/components/FilterPanel/index.d.ts +19 -0
  86. package/dist/filters/components/FilterPanel/index.js +36 -0
  87. package/dist/filters/filters/BooleanFilter/index.d.ts +3 -0
  88. package/dist/filters/filters/BooleanFilter/index.js +10 -0
  89. package/dist/filters/filters/CalendarFilter/index.d.ts +3 -0
  90. package/dist/filters/filters/CalendarFilter/index.js +10 -0
  91. package/dist/filters/filters/DateFilter/index.d.ts +3 -0
  92. package/dist/filters/filters/DateFilter/index.js +21 -0
  93. package/dist/filters/filters/DropdownFilter/index.d.ts +3 -0
  94. package/dist/filters/filters/DropdownFilter/index.js +10 -0
  95. package/dist/filters/filters/Filter/index.d.ts +16 -0
  96. package/dist/filters/filters/Filter/index.js +13 -0
  97. package/dist/filters/filters/MultiFilter/index.d.ts +3 -0
  98. package/dist/filters/filters/MultiFilter/index.js +9 -0
  99. package/dist/filters/filters/SearchFilter/index.d.ts +4 -0
  100. package/dist/filters/filters/SearchFilter/index.js +30 -0
  101. package/dist/filters/filters/interfaces.d.ts +10 -0
  102. package/dist/filters/filters/interfaces.js +1 -0
  103. package/dist/filters/hooks/useFilters.d.ts +5 -0
  104. package/dist/filters/hooks/useFilters.js +25 -0
  105. package/dist/filters/index.d.ts +2 -0
  106. package/dist/filters/index.js +2 -0
  107. package/dist/filters/interfaces.d.ts +28 -0
  108. package/dist/filters/interfaces.js +1 -0
  109. package/dist/filters/lang.d.ts +1 -0
  110. package/dist/filters/lang.js +1 -0
  111. package/dist/filters/utility/check-has-filters.d.ts +2 -0
  112. package/dist/filters/utility/check-has-filters.js +8 -0
  113. package/dist/filters/utility/create-client-filter-map.d.ts +3 -0
  114. package/dist/filters/utility/create-client-filter-map.js +14 -0
  115. package/dist/filters/utility/filter.d.ts +16 -0
  116. package/dist/filters/utility/filter.js +120 -0
  117. package/dist/filters/utility/get-quick-dates.d.ts +3 -0
  118. package/dist/filters/utility/get-quick-dates.js +90 -0
  119. package/dist/filters/utility/parse-filters.d.ts +3 -0
  120. package/dist/filters/utility/parse-filters.js +16 -0
  121. package/dist/filters/utility/parse-page.d.ts +2 -0
  122. package/dist/filters/utility/parse-page.js +8 -0
  123. package/dist/filters/utility/render-value.d.ts +3 -0
  124. package/dist/filters/utility/render-value.js +57 -0
  125. package/dist/filters/utility/transform-boolean.d.ts +2 -0
  126. package/dist/filters/utility/transform-boolean.js +10 -0
  127. package/dist/filters/utility/transform-date.d.ts +2 -0
  128. package/dist/filters/utility/transform-date.js +29 -0
  129. package/dist/filters/utility/transform-multi.d.ts +2 -0
  130. package/dist/filters/utility/transform-multi.js +9 -0
  131. package/dist/forms/components/Dropdown/index.d.ts +22 -0
  132. package/dist/forms/components/Dropdown/index.js +41 -0
  133. package/dist/forms/components/DropdownList/index.d.ts +8 -0
  134. package/dist/forms/components/DropdownList/index.js +20 -0
  135. package/dist/forms/components/EditableForm/index.d.ts +24 -0
  136. package/dist/forms/components/EditableForm/index.js +23 -0
  137. package/dist/forms/components/EditableFormField/index.d.ts +14 -0
  138. package/dist/forms/components/EditableFormField/index.js +37 -0
  139. package/dist/forms/components/EditableFormFields/index.d.ts +7 -0
  140. package/dist/forms/components/EditableFormFields/index.js +20 -0
  141. package/dist/forms/components/Form/index.d.ts +12 -0
  142. package/dist/forms/components/Form/index.js +9 -0
  143. package/dist/forms/components/FormError/index.d.ts +9 -0
  144. package/dist/forms/components/FormError/index.js +8 -0
  145. package/dist/forms/components/FormField/index.d.ts +25 -0
  146. package/dist/forms/components/FormField/index.js +37 -0
  147. package/dist/forms/components/FormFields/index.d.ts +10 -0
  148. package/dist/forms/components/FormFields/index.js +22 -0
  149. package/dist/forms/components/FormLabel/index.d.ts +10 -0
  150. package/dist/forms/components/FormLabel/index.js +8 -0
  151. package/dist/forms/components/FormSubmit/index.d.ts +4 -0
  152. package/dist/forms/components/FormSubmit/index.js +9 -0
  153. package/dist/forms/components/ModalForm/index.d.ts +13 -0
  154. package/dist/forms/components/ModalForm/index.js +25 -0
  155. package/dist/forms/components/PasswordInput/index.d.ts +11 -0
  156. package/dist/forms/components/PasswordInput/index.js +17 -0
  157. package/dist/forms/components/StaticTextInput/index.d.ts +22 -0
  158. package/dist/forms/components/StaticTextInput/index.js +22 -0
  159. package/dist/forms/components/Switch/index.d.ts +11 -0
  160. package/dist/forms/components/Switch/index.js +17 -0
  161. package/dist/forms/components/TextInput/index.d.ts +34 -0
  162. package/dist/forms/components/TextInput/index.js +30 -0
  163. package/dist/forms/hooks/useDropdown.d.ts +10 -0
  164. package/dist/forms/hooks/useDropdown.js +14 -0
  165. package/dist/forms/hooks/useEditableForm.d.ts +24 -0
  166. package/dist/forms/hooks/useEditableForm.js +34 -0
  167. package/dist/forms/hooks/useForm.d.ts +136 -0
  168. package/dist/forms/hooks/useForm.js +209 -0
  169. package/dist/forms/hooks/useModalForm.d.ts +14 -0
  170. package/dist/forms/hooks/useModalForm.js +29 -0
  171. package/dist/forms/index.d.ts +27 -0
  172. package/dist/forms/index.js +17 -0
  173. package/dist/forms/interfaces.d.ts +32 -0
  174. package/dist/forms/interfaces.js +1 -0
  175. package/dist/forms/utility/extract-editable-input-props.d.ts +8 -0
  176. package/dist/forms/utility/extract-editable-input-props.js +19 -0
  177. package/dist/forms/utility/extract-input-props.d.ts +9 -0
  178. package/dist/forms/utility/extract-input-props.js +37 -0
  179. package/dist/hooks/index.d.ts +0 -0
  180. package/dist/hooks/index.js +1 -0
  181. package/dist/hooks/useClickOutside.d.ts +93 -0
  182. package/dist/hooks/useClickOutside.js +124 -0
  183. package/dist/hooks/usePagination.d.ts +17 -0
  184. package/dist/hooks/usePagination.js +46 -0
  185. package/dist/hooks/useSearchParamsHref.d.ts +6 -0
  186. package/dist/hooks/useSearchParamsHref.js +33 -0
  187. package/dist/hooks/useToast.d.ts +18 -0
  188. package/dist/hooks/useToast.js +25 -0
  189. package/dist/navigation/components/AppNavigation/index.d.ts +13 -0
  190. package/dist/navigation/components/AppNavigation/index.js +15 -0
  191. package/dist/navigation/components/AppNavigationItem/index.d.ts +6 -0
  192. package/dist/navigation/components/AppNavigationItem/index.js +9 -0
  193. package/dist/navigation/components/Tabs/index.d.ts +7 -0
  194. package/dist/navigation/components/Tabs/index.js +9 -0
  195. package/dist/navigation/hooks/useNavigation.d.ts +10 -0
  196. package/dist/navigation/hooks/useNavigation.js +38 -0
  197. package/dist/navigation/index.d.ts +5 -0
  198. package/dist/navigation/index.js +3 -0
  199. package/dist/navigation/interfaces.d.ts +7 -0
  200. package/dist/navigation/interfaces.js +1 -0
  201. package/dist/styles/config.d.ts +64 -0
  202. package/dist/styles/config.js +43 -0
  203. package/dist/styles/icons.d.ts +15 -0
  204. package/dist/styles/icons.js +7 -0
  205. package/dist/styles/index.d.ts +2 -0
  206. package/dist/styles/index.js +1 -0
  207. package/dist/styles/interfaces.d.ts +41 -0
  208. package/dist/styles/interfaces.js +1 -0
  209. package/dist/styles/tw.d.ts +9 -0
  210. package/dist/styles/tw.js +15 -0
  211. package/dist/utility/index.d.ts +1 -0
  212. package/dist/utility/index.js +1 -0
  213. package/dist/utility/interfaces.d.ts +35 -0
  214. package/dist/utility/interfaces.js +1 -1
  215. package/package.json +55 -8
  216. package/dist/index.d.ts +0 -2
  217. package/dist/index.js +0 -1
  218. package/dist/lists/List/index.d.ts +0 -5
  219. package/dist/lists/List/index.js +0 -6
@@ -0,0 +1,9 @@
1
+ import type { ClassNameProps } from '../../../styles/interfaces';
2
+ import type { FormFieldClassNames } from '../FormField';
3
+ interface FormErrorProps extends ClassNameProps<FormFieldClassNames> {
4
+ children: React.ReactNode;
5
+ id: string;
6
+ isAssistive?: boolean;
7
+ }
8
+ declare function FormError({ children, classNames, classNameProps, id, isAssistive, }: Readonly<FormErrorProps>): React.ReactElement;
9
+ export default FormError;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { getClassNames } from '../../../styles/config';
3
+ import tw from '../../../styles/tw';
4
+ function FormError({ children, classNames, classNameProps, id, isAssistive, }) {
5
+ const componentClassNames = classNames || getClassNames('formField')?.(classNameProps);
6
+ return (_jsx("div", { className: tw(componentClassNames?.error, isAssistive ? 'sr-only' : null), id: `${id}_err`, children: children }));
7
+ }
8
+ export default FormError;
@@ -0,0 +1,25 @@
1
+ import type { InputEvent, InputProps } from '../../../forms/interfaces';
2
+ import type { ClassNameProps, ErrorableClassName } from '../../../styles/interfaces';
3
+ import { Action } from '../../../utility/interfaces';
4
+ export interface FormFieldClassNames {
5
+ root: ErrorableClassName;
6
+ label: string;
7
+ details: string;
8
+ optional: string;
9
+ field: string;
10
+ error: string;
11
+ }
12
+ export interface FormFieldProps<T, V extends T> extends ClassNameProps<FormFieldClassNames>, InputProps<T, V> {
13
+ action?: Action | null;
14
+ details?: string | null;
15
+ error?: Record<string, string> | null;
16
+ hasAssistiveError?: boolean;
17
+ hasAssistiveLabel?: boolean;
18
+ isContentOnly?: boolean;
19
+ isOptional?: boolean;
20
+ label?: React.ReactNode;
21
+ onChange?: (event: InputEvent<T>) => void;
22
+ render: (props: InputProps<T>) => React.ReactElement | null;
23
+ }
24
+ declare function FormField<T, V extends T>({ action, classNameProps, details, error, hasAssistiveError, hasAssistiveLabel, id, isContentOnly, isDisabled, isOptional, label, name, onChange, onKeyDown, render, value, }: Readonly<FormFieldProps<T, V>>): React.ReactElement | null;
25
+ export default FormField;
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { getClassNames } from '../../../styles/config';
5
+ import tw from '../../../styles/tw';
6
+ import FormError from '../FormError';
7
+ import FormLabel from '../FormLabel';
8
+ import ActionButton from '../../../components/buttons/ActionButton';
9
+ function checkHasError(error) {
10
+ return Boolean(error && Object.keys(error).length > 0 && Object.values(error).some(Boolean));
11
+ }
12
+ function FormField({ action, classNameProps, details, error, hasAssistiveError, hasAssistiveLabel, id, isContentOnly, isDisabled, isOptional, label, name, onChange, onKeyDown, render, value, }) {
13
+ const classNames = getClassNames('formField')?.(classNameProps);
14
+ const inputId = id || `ff_${name}`;
15
+ const [inputError, setInputError] = useState(null);
16
+ function handleError(message) {
17
+ setInputError(message);
18
+ }
19
+ const renderProps = {
20
+ classNameProps,
21
+ error,
22
+ hasError: checkHasError(error),
23
+ id: inputId,
24
+ isDisabled,
25
+ label,
26
+ name,
27
+ onChange,
28
+ onError: handleError,
29
+ onKeyDown,
30
+ value,
31
+ };
32
+ if (isContentOnly) {
33
+ return render(renderProps);
34
+ }
35
+ return (_jsxs("div", { className: tw(classNames?.root?.default, error ? classNames?.root?.error : null), children: [label ? (_jsx(FormLabel, { classNameProps: classNameProps, htmlFor: inputId, isAssistive: hasAssistiveLabel, isOptional: isOptional, children: label })) : null, details && label ? _jsx("div", { className: classNames?.details, children: details }) : null, _jsx("div", { className: classNames?.field, children: render(renderProps) }), action ? (_jsx("div", { children: _jsx(ActionButton, { ...action, isDisabled: Boolean(isDisabled || action.isDisabled) }) })) : null, inputError || error?.[name] ? (_jsx(FormError, { classNameProps: classNameProps, id: inputId, isAssistive: hasAssistiveError, children: inputError || error?.[name] })) : null] }));
36
+ }
37
+ export default FormField;
@@ -0,0 +1,10 @@
1
+ import type { FormFieldComponentProps } from '../../interfaces';
2
+ import type { DropdownComponentProps } from '../Dropdown';
3
+ import type { PasswordInputComponentProps } from '../PasswordInput';
4
+ import type { TextInputComponentProps } from '../TextInput';
5
+ export type DropdownFormFieldProps<T> = FormFieldComponentProps<T | null> & DropdownComponentProps<T>;
6
+ export declare function DropdownFormField<T>(props: Readonly<DropdownFormFieldProps<T>>): React.ReactElement;
7
+ export type PasswordFormFieldProps = FormFieldComponentProps<string> & PasswordInputComponentProps;
8
+ export declare function PasswordFormField(props: Readonly<PasswordFormFieldProps>): React.ReactElement;
9
+ export type TextFormFieldProps = FormFieldComponentProps<string> & TextInputComponentProps;
10
+ export declare function TextFormField(props: Readonly<TextFormFieldProps>): React.ReactElement;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback } from 'react';
3
+ import extractInputProps from '../../utility/extract-input-props';
4
+ import Dropdown from '../Dropdown';
5
+ import FormField from '../FormField';
6
+ import PasswordInput from '../PasswordInput';
7
+ import TextInput from '../TextInput';
8
+ export function DropdownFormField(props) {
9
+ const { fieldProps, inputProps } = extractInputProps(props);
10
+ const renderInput = useCallback((renderProps) => (_jsx(Dropdown, { ...renderProps, ...inputProps })), [inputProps]);
11
+ return _jsx(FormField, { ...fieldProps, render: renderInput });
12
+ }
13
+ export function PasswordFormField(props) {
14
+ const { fieldProps, inputProps } = extractInputProps(props);
15
+ const renderInput = useCallback((renderProps) => (_jsx(PasswordInput, { ...renderProps, ...inputProps })), [inputProps]);
16
+ return _jsx(FormField, { ...fieldProps, render: renderInput });
17
+ }
18
+ export function TextFormField(props) {
19
+ const { fieldProps, inputProps } = extractInputProps(props);
20
+ const renderInput = useCallback((renderProps) => (_jsx(TextInput, { ...renderProps, ...inputProps })), [inputProps]);
21
+ return _jsx(FormField, { ...fieldProps, render: renderInput });
22
+ }
@@ -0,0 +1,10 @@
1
+ import type { ClassNameProps } from '../../../styles/interfaces';
2
+ import type { FormFieldClassNames } from '../FormField';
3
+ interface FormLabelProps extends ClassNameProps<FormFieldClassNames> {
4
+ children: React.ReactNode;
5
+ htmlFor: string;
6
+ isAssistive?: boolean;
7
+ isOptional?: boolean;
8
+ }
9
+ declare function FormLabel({ children, classNames, classNameProps, htmlFor, isAssistive, isOptional, }: Readonly<FormLabelProps>): React.ReactElement;
10
+ export default FormLabel;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getClassNames } from '../../../styles/config';
3
+ import tw from '../../../styles/tw';
4
+ function FormLabel({ children, classNames, classNameProps, htmlFor, isAssistive, isOptional, }) {
5
+ const componentClassNames = classNames || getClassNames('formField')?.(classNameProps);
6
+ return (_jsxs("label", { className: tw(componentClassNames?.label, isAssistive ? 'sr-only' : null), htmlFor: htmlFor, children: [children, isOptional ? _jsx("small", { className: componentClassNames?.optional, children: "Optional" }) : null] }));
7
+ }
8
+ export default FormLabel;
@@ -0,0 +1,4 @@
1
+ import type { ButtonProps } from '../../../components/buttons/Button';
2
+ export type FormSubmitProps = Omit<ButtonProps, 'href' | 'isNewWindow' | 'isText'>;
3
+ declare function FormSubmit({ isLoading, ...props }: Readonly<FormSubmitProps>): React.ReactElement;
4
+ export default FormSubmit;
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useFormStatus } from 'react-dom';
4
+ import Button from '../../../components/buttons/Button';
5
+ function FormSubmit({ isLoading, ...props }) {
6
+ const { pending } = useFormStatus();
7
+ return _jsx(Button, { ...props, isLoading: isLoading || pending, type: "submit", variant: "primary" });
8
+ }
9
+ export default FormSubmit;
@@ -0,0 +1,13 @@
1
+ import type { ModalProps } from '../../../components/modals/Modal';
2
+ import type { FormProps } from '../Form';
3
+ export interface ModalFormProps {
4
+ children: React.ReactNode;
5
+ formProps: Omit<FormProps, 'children'>;
6
+ hasServerError?: boolean;
7
+ hasSubmit?: boolean;
8
+ isDisabled?: boolean;
9
+ modalProps: Omit<ModalProps, 'children'>;
10
+ submitLabel?: string;
11
+ }
12
+ declare function ModalForm({ children, formProps, hasServerError, hasSubmit, isDisabled, modalProps, submitLabel, }: Readonly<ModalFormProps>): React.ReactElement;
13
+ export default ModalForm;
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import Modal from '../../../components/modals/Modal';
4
+ import ModalActions from '../../../components/modals/ModalActions';
5
+ import useSearchParamsHref from '../../../hooks/useSearchParamsHref';
6
+ import Form from '../Form';
7
+ function ModalForm({ children, formProps, hasServerError, hasSubmit = true, isDisabled, modalProps, submitLabel, }) {
8
+ const { setSearchParamsHref } = useSearchParamsHref();
9
+ function handleCancel() {
10
+ setSearchParamsHref('action', null);
11
+ }
12
+ return (_jsx(Modal, { ...modalProps, children: _jsxs(Form, { ...formProps, children: [children, hasServerError ? _jsx("div", { children: "SERVER ERROR" }) : null, _jsx(ModalActions, { actions: [
13
+ { label: 'Cancel', onClick: handleCancel, variant: 'link' },
14
+ ...(modalProps.actions || []),
15
+ hasSubmit
16
+ ? {
17
+ isDisabled,
18
+ isLoading: modalProps.isLoading,
19
+ isSubmittable: true,
20
+ label: submitLabel || 'Submit',
21
+ }
22
+ : null,
23
+ ] })] }) }));
24
+ }
25
+ export default ModalForm;
@@ -0,0 +1,11 @@
1
+ import { InputProps } from '../../../forms/interfaces';
2
+ import type { ClassNameProps, SelectableClassName } from '../../../styles/interfaces';
3
+ import type { TextInputComponentProps } from '../TextInput';
4
+ export interface PasswordInputClassNames {
5
+ action: string;
6
+ icon: SelectableClassName;
7
+ }
8
+ export type PasswordInputComponentProps = TextInputComponentProps;
9
+ export type PasswordInputProps = ClassNameProps<PasswordInputClassNames> & InputProps<string> & PasswordInputComponentProps;
10
+ declare function PasswordInput({ classNameProps, classNames, ...props }: Readonly<PasswordInputProps>): React.ReactElement;
11
+ export default PasswordInput;
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { getClassNames } from '../../../styles/config';
5
+ import { getIcon } from '../../../styles/icons';
6
+ import tw from '../../../styles/tw';
7
+ import TextInput from '../TextInput';
8
+ function PasswordInput({ classNameProps, classNames, ...props }) {
9
+ const componentClassNames = classNames || getClassNames('passwordInput')?.(classNameProps);
10
+ const Icon = getIcon('password');
11
+ const [isVisible, setIsVisible] = useState(false);
12
+ function toggleVisible() {
13
+ setIsVisible(!isVisible);
14
+ }
15
+ return (_jsxs("div", { className: "relative", children: [_jsx(TextInput, { type: isVisible ? 'text' : 'password', ...props }), _jsx("div", { className: componentClassNames?.action, children: _jsxs("button", { className: tw(componentClassNames?.icon?.default, isVisible ? componentClassNames?.icon?.selected : null), onClick: toggleVisible, type: "button", children: [Icon ? _jsx(Icon, {}) : null, isVisible ? 'Hide' : 'Show'] }) })] }));
16
+ }
17
+ export default PasswordInput;
@@ -0,0 +1,22 @@
1
+ import type { InputProps } from '../../../forms/interfaces';
2
+ import type { ClassNameProps, ErrorableClassName } from '../../../styles/interfaces';
3
+ export interface StaticTextInputClassNames {
4
+ root: ErrorableClassName;
5
+ placeholder: string;
6
+ label: string;
7
+ details: string;
8
+ icon: string;
9
+ clear: string;
10
+ }
11
+ export interface StaticTextInputProps extends ClassNameProps<StaticTextInputClassNames>, Omit<InputProps<string[] | string, string[] | string>, 'onChange'> {
12
+ details?: string | null;
13
+ label: string;
14
+ icon?: React.ReactNode;
15
+ isOpen?: boolean;
16
+ isOptional?: boolean;
17
+ onClear?: () => void;
18
+ onClick?: React.MouseEventHandler<HTMLButtonElement>;
19
+ placeholder?: string;
20
+ }
21
+ declare function StaticTextInput({ classNames, classNameProps, details, hasError, icon, isDisabled, isOpen, isOptional, label, name, onClear, onClick, onKeyDown, placeholder, value, }: Readonly<StaticTextInputProps>): React.ReactElement;
22
+ export default StaticTextInput;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import Assistive from '../../../components/utility/Assistive';
4
+ import { getClassNames } from '../../../styles/config';
5
+ import tw from '../../../styles/tw';
6
+ function hasValue(value) {
7
+ if (Array.isArray(value)) {
8
+ return Boolean(value.filter((item) => Boolean(item)).length);
9
+ }
10
+ return Boolean(value);
11
+ }
12
+ function StaticTextInput({ classNames, classNameProps, details, hasError, icon, isDisabled, isOpen, isOptional, label, name, onClear, onClick, onKeyDown, placeholder = 'Select...', value, }) {
13
+ const componentClassNames = {
14
+ ...getClassNames('staticTextInput')?.(classNameProps),
15
+ ...classNames,
16
+ };
17
+ function handleClear() {
18
+ onClear?.();
19
+ }
20
+ return (_jsxs("div", { className: tw('relative', isDisabled ? 'pointer-events-none opacity-30' : null, componentClassNames.root?.default, hasError ? componentClassNames.root?.error : null), children: [_jsx("input", { name: name, type: "hidden", value: value ? value.toString() : '' }), label ? (_jsxs(Fragment, { children: [_jsx("span", { className: tw(componentClassNames.label), children: label }), details ? (_jsx("small", { className: tw(componentClassNames.details), children: details })) : null] })) : (_jsx("span", { className: tw(componentClassNames.placeholder), children: placeholder })), onClick ? (_jsx("button", { className: "absolute -bottom-px -left-px -right-px -top-px", disabled: isDisabled, onClick: onClick, onKeyDown: onKeyDown, tabIndex: 0, type: "button", children: _jsx(Assistive, { children: isOpen ? 'Close' : 'Open' }) })) : null, _jsxs("div", { className: "absolute bottom-0 right-0 top-0 flex w-0 items-center justify-end", children: [isOptional && hasValue(value) ? (_jsx("button", { className: tw('flex-none', componentClassNames.clear), onClick: handleClear, type: "button", children: _jsx(Assistive, { children: "Clear" }) })) : null, icon && !isDisabled ? (_jsx("i", { className: tw('pointer-events-none flex-none', componentClassNames.icon) })) : null] })] }));
21
+ }
22
+ export default StaticTextInput;
@@ -0,0 +1,11 @@
1
+ import type { InputProps } from '../../../forms/interfaces';
2
+ import { CheckableClassName, ClassNameProps } from '../../../styles/interfaces';
3
+ export interface SwitchClassNames {
4
+ root: string;
5
+ control: string;
6
+ input: CheckableClassName;
7
+ icon: CheckableClassName;
8
+ }
9
+ export type SwitchProps = ClassNameProps<SwitchClassNames> & InputProps<boolean>;
10
+ declare function Switch({ classNameProps, classNames, id, isDisabled, name, onChange, value, }: Readonly<SwitchProps>): React.ReactElement;
11
+ export default Switch;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import { getClassNames } from '../../../styles/config';
4
+ import tw from '../../../styles/tw';
5
+ function Switch({ classNameProps, classNames, id, isDisabled, name, onChange, value, }) {
6
+ const componentClassNames = classNames || getClassNames('switch')?.(classNameProps);
7
+ function handleChange(event) {
8
+ if (onChange) {
9
+ const inputEvent = {
10
+ target: { name, value: event.target.checked },
11
+ };
12
+ onChange(inputEvent);
13
+ }
14
+ }
15
+ return (_jsxs(Fragment, { children: [_jsx("input", { name: name, type: "hidden", value: "false" }), _jsx("div", { className: tw('block', componentClassNames?.root), children: _jsxs("div", { className: tw('relative', componentClassNames?.control), children: [_jsx("input", { "aria-checked": Boolean(value), checked: Boolean(value), className: tw('appearance-none', componentClassNames?.input?.default, value ? componentClassNames?.input?.checked : null), disabled: isDisabled, id: id || name, name: name, onChange: handleChange, type: "checkbox", value: "true" }), _jsx("i", { className: tw(componentClassNames?.icon?.default, value ? componentClassNames?.icon?.checked : null) })] }) })] }));
16
+ }
17
+ export default Switch;
@@ -0,0 +1,34 @@
1
+ import type { InputProps } from '../../../forms/interfaces';
2
+ import type { ClassNameProps, ErrorableClassName } from '../../../styles/interfaces';
3
+ export interface TextInputClassNames {
4
+ loading: string;
5
+ prefix: ErrorableClassName;
6
+ root: ErrorableClassName;
7
+ suffix: ErrorableClassName;
8
+ clear: string;
9
+ }
10
+ export interface TextInputComponentProps {
11
+ isAutocomplete?: boolean;
12
+ isLoading?: boolean;
13
+ onBlur?: React.EventHandler<React.FocusEvent>;
14
+ onFocus?: React.EventHandler<React.FocusEvent>;
15
+ placeholder?: string;
16
+ prefix?: string | null;
17
+ suffix?: string | null;
18
+ type?: React.HTMLInputTypeAttribute;
19
+ }
20
+ export type TextInputProps = ClassNameProps<TextInputClassNames> & InputProps<string> & TextInputComponentProps;
21
+ /**
22
+ *
23
+ * ## ClassNames
24
+ *
25
+ * | Name | Description | Type |
26
+ * | ---- | ----------- | ---- |
27
+ * | root | The input element itself | `ErrorableClassName` |
28
+ * | prefix | The prefix element of the input, if one exists | `ErrorableClassName` |
29
+ * | suffix | The suffix element of the input, if one exists | `ErrorableClassName` |
30
+ * | clear | The wrapper around the 'clear' button of the input, if one exists. The style of the
31
+ * button itself is handled by the `renderClear` prop. | `string` |
32
+ */
33
+ declare function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, prefix, suffix, type, value, }: Readonly<TextInputProps>): React.ReactElement;
34
+ export default TextInput;
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getClassNames } from '../../../styles/config';
3
+ import tw from '../../../styles/tw';
4
+ /**
5
+ *
6
+ * ## ClassNames
7
+ *
8
+ * | Name | Description | Type |
9
+ * | ---- | ----------- | ---- |
10
+ * | root | The input element itself | `ErrorableClassName` |
11
+ * | prefix | The prefix element of the input, if one exists | `ErrorableClassName` |
12
+ * | suffix | The suffix element of the input, if one exists | `ErrorableClassName` |
13
+ * | clear | The wrapper around the 'clear' button of the input, if one exists. The style of the
14
+ * button itself is handled by the `renderClear` prop. | `string` |
15
+ */
16
+ function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, prefix, suffix, type, value, }) {
17
+ const componentClassNames = classNames || getClassNames('textInput')?.(classNameProps);
18
+ function handleChange(event) {
19
+ if (onChange) {
20
+ const target = { name, value: event.target.value };
21
+ onChange({ target });
22
+ }
23
+ }
24
+ return (_jsxs("div", { className: tw('relative', prefix ? 'flex flex-row-reverse' : null, (!prefix && suffix) || value ? 'flex' : null, isDisabled ? 'pointer-events-none opacity-30' : null), children: [prefix ? _jsx("div", { children: prefix }) : null, _jsx("input", { "aria-invalid": hasError, "aria-labelledby": hasError
25
+ ? `${id || name}_err`
26
+ : undefined /* eslint-disable-line no-undefined */, autoComplete: isAutocomplete === false
27
+ ? '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
+ }
30
+ export default TextInput;
@@ -0,0 +1,10 @@
1
+ import { DropdownObject } from '../interfaces';
2
+ interface UseDropdownArgs<T extends string> {
3
+ deps?: unknown[];
4
+ fn: (...args: unknown[]) => Promise<DropdownObject<T>[]>;
5
+ }
6
+ interface UseDropdownReturn<T extends string> {
7
+ data: DropdownObject<T>[];
8
+ }
9
+ declare function useDropdown<T extends string>({ deps, fn }: UseDropdownArgs<T>): UseDropdownReturn<T>;
10
+ export default useDropdown;
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { useEffect, useState } from 'react';
3
+ function useDropdown({ deps, fn }) {
4
+ const [data, setData] = useState([]);
5
+ async function getData() {
6
+ const response = await (deps ? fn(...deps) : fn());
7
+ setData(response);
8
+ }
9
+ useEffect(() => {
10
+ void getData();
11
+ }, deps || []);
12
+ return { data };
13
+ }
14
+ export default useDropdown;
@@ -0,0 +1,24 @@
1
+ import type { EditableFormProps } from '../components/EditableForm';
2
+ import type { EditingStatus } from '../interfaces';
3
+ import type { FieldPropsReturn, UseFormArgs, UseFormReturn } from './useForm';
4
+ export interface EditableFieldPropsReturn<Request, K extends keyof Request = keyof Request> extends FieldPropsReturn<Request, K> {
5
+ status: EditingStatus | null;
6
+ }
7
+ export type UseEditableFormArgs<Request, Response> = UseFormArgs<Request, Response> & {
8
+ defaultStatus?: EditingStatus;
9
+ onCancel?: () => void;
10
+ onEdit?: () => void;
11
+ title?: string;
12
+ };
13
+ export interface UseEditableFormReturn<Request> extends Omit<UseFormReturn<Request>, 'fieldProps' | 'formProps'> {
14
+ actionProps: {
15
+ setStatus: React.Dispatch<React.SetStateAction<EditingStatus | null>>;
16
+ status: EditingStatus | null;
17
+ };
18
+ fieldProps: <K extends keyof Request>(name: K, label?: string) => FieldPropsReturn<Request, K>;
19
+ formProps: Omit<EditableFormProps, 'children'>;
20
+ setStatus: React.Dispatch<React.SetStateAction<EditingStatus | null>>;
21
+ status: EditingStatus | null;
22
+ }
23
+ declare function useEditableForm<Request extends object, Response = Request>({ defaultStatus, onCancel, onEdit, onSuccess, title, ...args }: UseEditableFormArgs<Request, Response>): UseEditableFormReturn<Request>;
24
+ export default useEditableForm;
@@ -0,0 +1,34 @@
1
+ import { useEffect, useState } from 'react';
2
+ import useForm from './useForm';
3
+ function useEditableForm({ defaultStatus, onCancel, onEdit, onSuccess, title, ...args }) {
4
+ const [status, setStatus] = useState(defaultStatus ?? null);
5
+ async function onEditableSuccess(response) {
6
+ if (onSuccess) {
7
+ await onSuccess(response);
8
+ }
9
+ setStatus('SAVED');
10
+ }
11
+ const useFormReturn = useForm({
12
+ ...args,
13
+ refreshOnSuccess: true,
14
+ onSuccess: onEditableSuccess,
15
+ });
16
+ function editableFieldProps(name, label) {
17
+ const fieldProps = useFormReturn.fieldProps(name, label);
18
+ return { ...fieldProps, status };
19
+ }
20
+ useEffect(() => {
21
+ if (status === 'CANCELLED') {
22
+ useFormReturn.setErrors(null);
23
+ }
24
+ }, [status]);
25
+ return {
26
+ ...useFormReturn,
27
+ actionProps: { status, setStatus },
28
+ fieldProps: editableFieldProps,
29
+ formProps: { formProps: useFormReturn.formProps, onCancel, onEdit, status, setStatus, title },
30
+ status,
31
+ setStatus,
32
+ };
33
+ }
34
+ export default useEditableForm;
@@ -0,0 +1,136 @@
1
+ import type { Default, InputEvent } from '../../forms/interfaces';
2
+ 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
+ export interface FieldPropsReturn<Request, K extends keyof Request = keyof Request> {
10
+ error: Record<string, string> | null;
11
+ isDisabled?: boolean;
12
+ label?: string;
13
+ name: string;
14
+ onChange: (event: InputEvent<Request[K]>) => void;
15
+ value: Request[K];
16
+ }
17
+ export interface ToastsArgs {
18
+ server?: string | false;
19
+ success?: string | false;
20
+ validation?: string | false;
21
+ }
22
+ export interface UseFormArgs<Request, Response> {
23
+ defaults?: Default<Request>;
24
+ onError?: (message: string) => void;
25
+ 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;
30
+ toasts?: ToastsArgs | false;
31
+ }
32
+ export interface UseFormReturn<Request> {
33
+ errors: Record<string, string> | null;
34
+ fieldProps: <K extends keyof Request>(name: K, label?: string) => FieldPropsReturn<Request, K>;
35
+ formData: Partial<Request>;
36
+ formProps: Omit<FormProps, 'children'>;
37
+ isLoading: boolean;
38
+ resetForm: () => void;
39
+ setErrors: (errors: Record<string, string> | null) => void;
40
+ setFormData: (key: keyof Request, value: Request[keyof Request]) => void;
41
+ submitForm: () => void;
42
+ }
43
+ /**
44
+ * ## Overview
45
+ *
46
+ * `useForm` is a custom React hook that facilitates handling server-side form submission,
47
+ * including state management, error handling, and form data processing. It's designed to work
48
+ * with forms where the data is submitted to and validated by a server.
49
+ *
50
+ * ## Type Parameters
51
+ *
52
+ * - `Request extends object`: The shape of the request data.
53
+ * - `Response = Request`: The shape of the response data, defaulting to the same type as `Request`.
54
+ *
55
+ * ## Arguments
56
+ *
57
+ * `useForm` takes an object with the following properties:
58
+ *
59
+ * - `defaults`: Initial default values for the form data.
60
+ * - `hiddenFields`: Fields that should be included in the form submission but not displayed.
61
+ * - `onError`: Callback function for handling errors during form submission.
62
+ * - `onSubmit`: Function to handle the form submission. Expected to return a promise.
63
+ * - `onSuccess`: Callback function to be called upon a successful submission.
64
+ * - `onValidationError`: Callback function for handling validation errors.
65
+ * - `toasts`: Configuration for displaying success or error toasts.
66
+ *
67
+ * ## Returns
68
+ *
69
+ * `useForm` returns an object with the following properties:
70
+ *
71
+ * - `errors`: An object containing any form errors.
72
+ * - `fieldProps`: Function to generate props for a form field.
73
+ * - `formData`: Current form data.
74
+ * - `formProps`: Props for the form element including the submit handler.
75
+ * - `isLoading`: Boolean indicating if the form submission is in progress.
76
+ * - `resetForm`: Function to reset the form to its initial state.
77
+ * - `setFormData`: Function to update a specific piece of form data.
78
+ *
79
+ * ## Functionality
80
+ *
81
+ * - **Form Data Management:**
82
+ * - Manages form data state and provides handleChange and setFormData functions to update form
83
+ * data.
84
+ *
85
+ * - **Form Submission:**
86
+ * - Handles form submission, including displaying loading state, submitting data to the provided
87
+ * onSubmit function, and handling server-side validation errors or other errors.
88
+ *
89
+ * - **Error Handling:**
90
+ * - Manages form error state and handles displaying error messages.
91
+ *
92
+ * - **Toasts:**
93
+ * - Optionally displays success or error toasts based on the form submission outcome.
94
+ *
95
+ * - **Reset Form:**
96
+ * - Provides a function to reset the form to its default state.
97
+ *
98
+ * ## Example
99
+ *
100
+ * ```jsx
101
+ * import React from 'react';
102
+ * import { useForm } from './path-to-useForm';
103
+ *
104
+ * const MyFormComponent = () => {
105
+ * const { fieldProps, formProps, isLoading, resetForm } = useForm<MyFormData>({
106
+ * defaults: { name: '', email: '' },
107
+ * onSubmit: async (formData) => {
108
+ * // Submit form data to the server
109
+ * },
110
+ * });
111
+ *
112
+ * return (
113
+ * <form {...formProps}>
114
+ * <input {...fieldProps('name', 'Name')} />
115
+ * <input {...fieldProps('email', 'Email')} />
116
+ * <button type="submit" disabled={isLoading}>Submit</button>
117
+ * <button type="button" onClick={resetForm}>Reset</button>
118
+ * </form>
119
+ * );
120
+ * };
121
+ *
122
+ * export default MyFormComponent;
123
+ * ```
124
+ *
125
+ * In this example, `MyFormComponent` uses the `useForm` hook to manage form state, handle
126
+ * submissions, display errors, and reset the form.
127
+ *
128
+ * ## Notes
129
+ *
130
+ * - Ensure proper types are passed to the useForm hook to align with the expected structure
131
+ * of your form data and server responses.
132
+ * - The hook's functionality can be extended or customized based on specific use cases, such as
133
+ * handling additional form events or integrating with different server APIs.
134
+ */
135
+ declare function useForm<Request extends object, Response = Request>({ defaults, onError, onSubmit, onSuccess, onValidation, redirectOnSuccess, refreshOnSuccess, toasts, }: UseFormArgs<Request, Response>): UseFormReturn<Request>;
136
+ export default useForm;