@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,7 @@
1
+ import type { Action } from '../../../utility/interfaces';
2
+ type ActionButtonProps = Omit<Action, 'label'> & {
3
+ readonly children?: React.ReactNode;
4
+ readonly label?: React.ReactNode;
5
+ };
6
+ declare function ActionButton(props: ActionButtonProps): React.ReactElement;
7
+ export default ActionButton;
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import Button from '../../../components/buttons/Button';
4
+ import ConfirmableButton from '../../../components/buttons/ConfirmableButton';
5
+ import FormSubmit from '../../../forms/components/FormSubmit';
6
+ import useSearchParamsHref from '../../../hooks/useSearchParamsHref';
7
+ import { Suspense } from 'react';
8
+ function ActionButtonComponent({ action, children, confirmable, href, icon, isDisabled, isLoading, isSubmittable, label, onClick, variant, }) {
9
+ const { setSearchParamsHref } = useSearchParamsHref();
10
+ function handleClick() {
11
+ onClick?.();
12
+ if (action) {
13
+ setSearchParamsHref({ action });
14
+ }
15
+ }
16
+ const componentProps = {
17
+ children: children ?? label,
18
+ href,
19
+ icon,
20
+ isDisabled: Boolean(isDisabled || isLoading),
21
+ isLoading: isLoading && (isSubmittable || variant === 'primary'),
22
+ onClick: handleClick,
23
+ variant,
24
+ };
25
+ if (confirmable) {
26
+ return _jsx(ConfirmableButton, { ...componentProps, confirmable: confirmable });
27
+ }
28
+ return isSubmittable ? _jsx(FormSubmit, { ...componentProps }) : _jsx(Button, { ...componentProps });
29
+ }
30
+ function ActionButton(props) {
31
+ return (_jsx(Suspense, { children: _jsx(ActionButtonComponent, { ...props }) }));
32
+ }
33
+ export default ActionButton;
@@ -0,0 +1,65 @@
1
+ import type { ClassNameProps, StylableButtonClassName } from '../../../styles/interfaces';
2
+ import { ButtonVariant } from '../../../utility/interfaces';
3
+ export interface ButtonClassNames {
4
+ root: StylableButtonClassName;
5
+ icon: string;
6
+ }
7
+ export interface ButtonProps extends ClassNameProps<ButtonClassNames> {
8
+ /** Probably the button text, but could be any HTML element or React component */
9
+ readonly children: React.ReactNode;
10
+ /** Lets you associate the Button to forms anywhere in the document */
11
+ readonly form?: string;
12
+ /** If true, the Button content will be hidden visually without hiding it from screen readers */
13
+ readonly hasAssistiveLabel?: boolean;
14
+ /** If specified, the Button will be created as a Link element. */
15
+ readonly href?: string;
16
+ /** An optional icon to display alongside the button text */
17
+ readonly icon?: React.ReactNode;
18
+ /** An optional id to assign to the button element */
19
+ readonly id?: string;
20
+ /** If true, the Button will be greyed out and non-interactive */
21
+ readonly isDisabled?: boolean;
22
+ /** If true, the button will stretch to the full width of its container */
23
+ readonly isFullWidth?: boolean;
24
+ /** If true, the Button will show a loading indicator, and be non-interactive */
25
+ readonly isLoading?: boolean;
26
+ /** If true, and the Button has a `href` prop, it will open the link in a new window/tab */
27
+ readonly isNewWindow?: boolean;
28
+ /** If true, the Button will be rendered as a text link. It will still act as a button. */
29
+ readonly isText?: boolean;
30
+ /** Used in situations where the button needs to be identified by name */
31
+ readonly name?: string;
32
+ /** An event handler for when the button is clicked */
33
+ readonly onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLButtonElement>;
34
+ /** If specified, a Popover component can be anchored to the target element with this ID */
35
+ readonly popoverTarget?: string;
36
+ readonly scroll?: boolean;
37
+ readonly style?: React.CSSProperties;
38
+ /** The type of button. Button's with a type of `submit` will submit a parent form */
39
+ readonly type?: 'button' | 'submit';
40
+ /** Used in situations where a button value needs to be submitted with a form */
41
+ readonly value?: string;
42
+ /** A set of predefined variants that can be passed to the classNames config to customize the button's appearance */
43
+ readonly variant?: ButtonVariant;
44
+ }
45
+ /**
46
+ * Either a `Link` component or a `button` element, depending on whether a `href` prop is specified.
47
+ *
48
+ * As a `Link`, it provides navigation between pages, and as a `button` it will handle the
49
+ * `onClick` function when clicked (if one is specified).
50
+ *
51
+ * ## Using href & onClick
52
+ *
53
+ * Although it is possible to omit both the `href` and `onClick` props, there will
54
+ * be nearly zero situations where this would be useful. It is also possible to include both props.
55
+ * This will create a `Link` component, and handle the `onClick` function before navigation. Calling
56
+ * `e.preventDefault()` in the `onClick` function will prevent the navigation from occurring.
57
+ *
58
+ * ## ClassNames
59
+ *
60
+ * | Name | Description | Type |
61
+ * | ---- | ----------- | ---- |
62
+ * | root | The button element | `StylableButtonClassName` |
63
+ */
64
+ declare function Button({ children, classNames, classNameProps, form, hasAssistiveLabel, href, icon, id, isDisabled, isFullWidth, isLoading, isNewWindow, isText, name, onClick, popoverTarget, scroll, style, type, value, variant, }: ButtonProps): React.ReactElement;
65
+ export default Button;
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useRef } from 'react';
4
+ import Link from '../../../components/utility/Link';
5
+ import Loader from '../../../components/utility/Loader';
6
+ import { getClassNames } from '../../../styles/config';
7
+ import tw from '../../../styles/tw';
8
+ function getVariantClassName(className, variant) {
9
+ if (!className || !variant) {
10
+ return null;
11
+ }
12
+ return className[variant] || null;
13
+ }
14
+ /**
15
+ * Either a `Link` component or a `button` element, depending on whether a `href` prop is specified.
16
+ *
17
+ * As a `Link`, it provides navigation between pages, and as a `button` it will handle the
18
+ * `onClick` function when clicked (if one is specified).
19
+ *
20
+ * ## Using href & onClick
21
+ *
22
+ * Although it is possible to omit both the `href` and `onClick` props, there will
23
+ * be nearly zero situations where this would be useful. It is also possible to include both props.
24
+ * This will create a `Link` component, and handle the `onClick` function before navigation. Calling
25
+ * `e.preventDefault()` in the `onClick` function will prevent the navigation from occurring.
26
+ *
27
+ * ## ClassNames
28
+ *
29
+ * | Name | Description | Type |
30
+ * | ---- | ----------- | ---- |
31
+ * | root | The button element | `StylableButtonClassName` |
32
+ */
33
+ function Button({ children, classNames, classNameProps, form, hasAssistiveLabel, href, icon, id, isDisabled, isFullWidth, isLoading, isNewWindow, isText, name, onClick, popoverTarget, scroll, style, type, value, variant, }) {
34
+ const ref = useRef(null);
35
+ const componentClassNames = classNames ||
36
+ getClassNames(isText ? 'textButton' : 'button')?.({
37
+ ...(classNameProps || {}),
38
+ hasAssistiveLabel,
39
+ });
40
+ const className = tw('flex cursor-pointer items-center justify-center whitespace-nowrap', isDisabled || isLoading ? 'pointer-events-none opacity-30' : null, isFullWidth ? 'w-full' : null, componentClassNames?.root?.default, getVariantClassName(componentClassNames?.root, variant));
41
+ /*
42
+ * Link uses classNames, whereas button uses className. This is because Link can also be used
43
+ * headless in other applications, and so should have consistency.
44
+ */
45
+ if (href) {
46
+ return (_jsx(Link, { className: className, href: href, id: id, isNewWindow: isNewWindow, onClick: onClick, scroll: scroll, style: style, children: _jsxs("span", { className: "flex items-center gap-2", children: [icon ? (_jsx("span", { className: tw('flex-none', componentClassNames?.icon), children: icon })) : null, _jsx("span", { className: tw(hasAssistiveLabel ? 'sr-only' : null), children: children })] }) }));
47
+ }
48
+ return (_jsxs("button", { ref: ref, className: className, disabled: isDisabled || isLoading || false, form: form, id: id, name: name, onClick: onClick, popoverTarget: popoverTarget, style: style, type: type === 'submit' ? 'submit' : 'button', value: value, children: [isLoading ? (_jsx("div", { className: "absolute left-1/2 top-1/2 -translate-x-2/4 -translate-y-2/4", children: _jsx(Loader, {}) })) : null, _jsxs("span", { className: "flex items-center gap-2", children: [icon ? (_jsx("span", { className: tw('flex-none', componentClassNames?.icon), children: icon })) : null, _jsx("span", { className: tw(hasAssistiveLabel ? 'sr-only' : null), children: children })] })] }));
49
+ }
50
+ export default Button;
@@ -0,0 +1,7 @@
1
+ import type { ConfirmableObject } from '../../../utility/interfaces';
2
+ import type { ButtonProps } from '../Button';
3
+ export type ConfirmableButtonProps = ButtonProps & {
4
+ confirmable: ConfirmableObject;
5
+ };
6
+ declare function ConfirmableButton({ confirmable, ...buttonProps }: Readonly<ConfirmableButtonProps>): React.ReactElement;
7
+ export default ConfirmableButton;
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Fragment } from 'react';
4
+ import Button from '../Button';
5
+ function ConfirmableButton({ confirmable, ...buttonProps }) {
6
+ // const { handle, modalProps } = useConfirmable<HTMLButtonElement>({
7
+ // isLoading,
8
+ // onBeforeConfirm,
9
+ // onConfirm: (event) => onClick?.(event),
10
+ // });
11
+ return (_jsx(Fragment, { children: _jsx(Button, { ...buttonProps, icon: confirmable.icon, isLoading: confirmable.isLoading }) }));
12
+ }
13
+ export default ConfirmableButton;
@@ -0,0 +1,5 @@
1
+ import type { ButtonClassNames, ButtonProps } from '../Button';
2
+ export type TextButtonClassNames = ButtonClassNames;
3
+ export type TextButtonProps = Omit<ButtonProps, 'isText'>;
4
+ declare function TextButton(props: TextButtonProps): React.ReactElement;
5
+ export default TextButton;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Button from '../Button';
3
+ function TextButton(props) {
4
+ return _jsx(Button, { ...props, isText: true });
5
+ }
6
+ export default TextButton;
@@ -0,0 +1,15 @@
1
+ import type { FilterMap } from '../../../filters/interfaces';
2
+ import type { NextPageProps } from '../../../utility/interfaces';
3
+ import type { EmptyMessageProps } from '../EmptyMessage';
4
+ import type { ListFunctionConfig, Paginated } from '../interfaces';
5
+ export interface CollectionProps<Item, Transformed, Filters = null> {
6
+ readonly data?: Item[] | Paginated<Item>;
7
+ readonly emptyMessageProps?: EmptyMessageProps;
8
+ readonly filterMap?: FilterMap<Filters>;
9
+ readonly fn?: (config: ListFunctionConfig<Filters>) => Promise<Item[]> | Promise<Paginated<Item>>;
10
+ readonly pageProps?: NextPageProps;
11
+ readonly render: (data: Transformed[]) => React.ReactElement;
12
+ readonly transformer: (item: Item) => Transformed;
13
+ }
14
+ declare function Collection<Item extends object, Transformed, Filters>({ filterMap, ...props }: CollectionProps<Item, Transformed, Filters>): React.ReactElement;
15
+ export default Collection;
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment, Suspense } from 'react';
3
+ import Loader from '../../../components/utility/Loader';
4
+ import FilterBar from '../../../filters/components/FilterBar';
5
+ import checkHasFilters from '../../../filters/utility/check-has-filters';
6
+ import parseFilters from '../../../filters/utility/parse-filters';
7
+ import parsePage from '../../../filters/utility/parse-page';
8
+ import { getIcon } from '../../../styles/icons';
9
+ import EmptyMessage from '../EmptyMessage';
10
+ import Pagination from '../Pagination';
11
+ import isPaginated from '../utility/is-paginated';
12
+ import { messages } from '../lang';
13
+ async function CollectionComponent({ data, emptyMessageProps, filterMap, fn, pageProps, render, transformer, }) {
14
+ const EmptyIcon = getIcon('collection.empty');
15
+ const awaitedParams = pageProps?.params ? await pageProps.params : null;
16
+ const awaitedSearchParams = pageProps?.searchParams ? await pageProps.searchParams : null;
17
+ async function getResponse() {
18
+ if (typeof data !== 'undefined') {
19
+ return data;
20
+ }
21
+ if (typeof fn === 'undefined') {
22
+ throw new Error('ListComponent: Either `data` or `fn` must be provided.');
23
+ }
24
+ const filters = parseFilters(awaitedSearchParams, filterMap);
25
+ const page = parsePage(awaitedSearchParams);
26
+ return fn({ filters, page, params: awaitedParams });
27
+ }
28
+ const response = await getResponse();
29
+ const dynamicData = (isPaginated(response) ? response.data : response).map(transformer);
30
+ const componentEmptyMessageProps = checkHasFilters(awaitedSearchParams)
31
+ ? {
32
+ children: messages.EMPTY_FILTER_DESCRIPTION,
33
+ icon: EmptyIcon ? _jsx(EmptyIcon, {}) : null,
34
+ title: messages.EMPTY_FILTER_TITLE,
35
+ }
36
+ : emptyMessageProps;
37
+ if (!dynamicData.length) {
38
+ return _jsx(EmptyMessage, { ...componentEmptyMessageProps });
39
+ }
40
+ return (_jsxs(Fragment, { children: [render(dynamicData), isPaginated(response) ? (_jsx(Pagination, { ...response.meta, nextLabel: "Next \u2192", previousLabel: "\u2190 Previous" })) : null] }));
41
+ }
42
+ function Collection({ filterMap, ...props }) {
43
+ return (_jsxs(Fragment, { children: [filterMap ? _jsx(FilterBar, { map: filterMap }) : null, _jsx(Suspense, { fallback: _jsx("div", { className: "flex justify-center p-16", children: _jsx(Loader, {}) }), children: _jsx(CollectionComponent, { ...props, filterMap: filterMap }) })] }));
44
+ }
45
+ export default Collection;
@@ -0,0 +1,26 @@
1
+ import type { ClassNameProps, StylableClassName } from '../../../styles/interfaces';
2
+ import { StyleVariant } from '../../../utility/interfaces';
3
+ import type { EmptyMessageActionProps } from '../EmptyMessageAction';
4
+ export interface EmptyMessageClassNames {
5
+ root: StylableClassName;
6
+ description: string;
7
+ icon: StylableClassName;
8
+ title: StylableClassName;
9
+ action: string;
10
+ }
11
+ export interface EmptyMessageProps extends ClassNameProps<EmptyMessageClassNames> {
12
+ action?: EmptyMessageActionProps['action'] | null;
13
+ children?: React.ReactNode;
14
+ icon?: React.ReactNode;
15
+ title?: string;
16
+ variant?: StyleVariant | null;
17
+ }
18
+ export declare const DEFAULT_TITLE = "No results found";
19
+ export declare const DEFAULT_CHILDREN = "If you think this is an error, please contact the site administrator.";
20
+ /**
21
+ * By default, `EmptyMessage` simply displays a message to the user when no results have been found
22
+ * in a particular list. However, the `title` and `description` can be customised, allowing the
23
+ * component to be used for any situation where a standout message is required.
24
+ */
25
+ declare function EmptyMessage({ action, children, classNameProps, classNames, icon, title, variant, }: Readonly<EmptyMessageProps>): React.ReactElement;
26
+ export default EmptyMessage;
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { getClassNames } from '../../../styles/config';
4
+ import tw from '../../../styles/tw';
5
+ import EmptyMessageAction from '../EmptyMessageAction';
6
+ export const DEFAULT_TITLE = 'No results found';
7
+ export const DEFAULT_CHILDREN = 'If you think this is an error, please contact the site administrator.';
8
+ /**
9
+ * By default, `EmptyMessage` simply displays a message to the user when no results have been found
10
+ * in a particular list. However, the `title` and `description` can be customised, allowing the
11
+ * component to be used for any situation where a standout message is required.
12
+ */
13
+ function EmptyMessage({ action, children = DEFAULT_CHILDREN, classNameProps, classNames, icon, title = DEFAULT_TITLE, variant, }) {
14
+ const componentClassNames = classNames || getClassNames('emptyMessage')?.(classNameProps);
15
+ return (_jsxs("section", { className: tw(componentClassNames?.root?.default, variant ? componentClassNames?.root?.[variant] : null), children: [icon ? (_jsx("div", { className: tw(componentClassNames?.icon?.default, variant ? componentClassNames?.icon?.[variant] : null), children: icon })) : null, _jsx("h2", { className: tw(componentClassNames?.title?.default, variant ? componentClassNames?.title?.[variant] : null), children: title }), _jsx("div", { className: tw(componentClassNames?.description), children: children }), action ? (_jsx("div", { className: tw(componentClassNames?.action), children: _jsx(EmptyMessageAction, { action: action }) })) : null] }));
16
+ }
17
+ export default EmptyMessage;
@@ -0,0 +1,6 @@
1
+ import { Action } from '../../../utility/interfaces';
2
+ export interface EmptyMessageActionProps {
3
+ action: Action | React.ReactElement;
4
+ }
5
+ declare function EmptyMessageAction({ action }: Readonly<EmptyMessageActionProps>): React.ReactElement;
6
+ export default EmptyMessageAction;
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { isValidElement } from 'react';
4
+ import Button from '../../../components/buttons/Button';
5
+ import useSearchParamsHref from '../../../hooks/useSearchParamsHref';
6
+ function EmptyMessageAction({ action }) {
7
+ const { getSearchParamsHref } = useSearchParamsHref();
8
+ if (isValidElement(action)) {
9
+ return action;
10
+ }
11
+ function handleClick() {
12
+ if ('onClick' in action && typeof action.onClick === 'function') {
13
+ action.onClick();
14
+ }
15
+ }
16
+ const href = action.action ? getSearchParamsHref('action', action.action) : action.href;
17
+ return (_jsx(Button, { href: href, isDisabled: Boolean(action.isDisabled), onClick: handleClick, variant: "primary", children: action.label }));
18
+ }
19
+ export default EmptyMessageAction;
@@ -0,0 +1,6 @@
1
+ import { CollectionProps } from '../Collection';
2
+ import type { ListItemObject } from '../interfaces';
3
+ export interface ListProps<Item, Filters = null, Data extends object | null = null> extends Omit<CollectionProps<Item, ListItemObject<Data>, Filters>, 'render'> {
4
+ }
5
+ declare function List<Item extends object, Filters, Data extends object | null = null>(props: ListProps<Item, Filters, Data>): React.ReactElement;
6
+ export default List;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Collection from '../Collection';
3
+ import ListClientComponent from '../ListClientComponent';
4
+ function defaultTransformer(item) {
5
+ return {
6
+ id: 'id' in item ? String(item.id) : JSON.stringify(item),
7
+ title: 'title' in item ? String(item.title) : '',
8
+ };
9
+ }
10
+ function List(props) {
11
+ return (_jsx(Collection, { ...props, render: (data) => _jsx(ListClientComponent, { data: data }), transformer: props.transformer ?? defaultTransformer }));
12
+ }
13
+ export default List;
@@ -0,0 +1,7 @@
1
+ import type { ListItemObject } from '../interfaces';
2
+ export interface ListClientComponentProps<Data extends object | null = null> {
3
+ data: ListItemObject<Data>[];
4
+ renderItem?: (props: ListItemObject<Data>) => React.ReactElement;
5
+ }
6
+ declare function ListClientComponent<Data extends object | null = null>({ data, renderItem, }: Readonly<ListClientComponentProps<Data>>): React.ReactElement;
7
+ export default ListClientComponent;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import ListItem from '../ListItem';
4
+ function ListClientComponent({
5
+ // actions,
6
+ data, renderItem = ListItem, }) {
7
+ return (_jsx("ul", { className: "", children: data.map((item) => (_jsx(Fragment, { children: renderItem({ /*actions,*/ ...item }) }, item.id))) }));
8
+ }
9
+ export default ListClientComponent;
@@ -0,0 +1,14 @@
1
+ import type { ClassNameProps, StylableClassName } from '../../../styles/interfaces';
2
+ import type { ListItemObject } from '../interfaces';
3
+ export interface ListItemClassNames {
4
+ description: string;
5
+ primary: string;
6
+ root: StylableClassName;
7
+ secondary: string;
8
+ tertiary: string;
9
+ title: StylableClassName;
10
+ }
11
+ export interface ListItemProps<Data extends object | null = null> extends ClassNameProps<ListItemClassNames>, ListItemObject<Data> {
12
+ }
13
+ declare function ListItem<Data extends object | null = null>({ classNames, classNameProps, description, href, id, isLoading, meta, secondary, tertiary, title, variant, }: Readonly<ListItemProps<Data>>): React.ReactElement;
14
+ export default ListItem;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // import type { MenuAction } from '../../elements/MenuItem';
3
+ import { getClassNames } from '../../../styles/config';
4
+ import tw from '../../../styles/tw';
5
+ import Link from '../../../components/utility/Link';
6
+ import ListItemSecondary from '../ListItemSecondary';
7
+ import ListItemMeta from '../ListItemMeta';
8
+ const colMap = {
9
+ 1: 'grid-cols-1',
10
+ 2: 'grid-cols-1 @lg:grid-cols-[1fr_1fr]',
11
+ 3: 'grid-cols-1 @lg:grid-cols-[3fr_1fr_2fr] @2xl:grid-cols-[2fr_1fr_1fr]',
12
+ };
13
+ function getLayout(layout) {
14
+ const count = layout.filter(Boolean).length;
15
+ return colMap[count];
16
+ }
17
+ function ListItem({
18
+ // actions,
19
+ classNames, classNameProps, description, href, id, isLoading, meta, secondary, tertiary, title, variant, }) {
20
+ const componentClassNames = classNames || getClassNames('listItem')?.(classNameProps);
21
+ const hasPrimary = Boolean(title || description || meta);
22
+ const hasSecondary = Boolean(secondary);
23
+ const hasTertiary = Boolean(tertiary);
24
+ return (_jsx("li", { className: tw('@container relative grid', componentClassNames?.root?.default, variant ? componentClassNames?.root?.[variant] : null, isLoading ? 'pointer-events-none animate-pulse' : null
25
+ // typeof actions === 'function' ? 'grid-cols-[1fr_auto] gap-4' : 'grid-cols-1'
26
+ ), children: _jsx("article", { className: "contents", children: _jsxs("div", { className: tw('grid gap-x-6 gap-y-4', getLayout([hasPrimary, hasSecondary, hasTertiary])), children: [_jsxs("div", { className: componentClassNames?.primary, children: [title ? (_jsx("h2", { className: tw(componentClassNames?.title?.default, variant ? componentClassNames?.title?.[variant] : null), children: href ? (_jsx(Link, { className: "hover:text-link", href: href, children: title })) : (title) })) : null, description ? (_jsx("div", { className: componentClassNames?.description, children: description })) : null, _jsx(ListItemMeta, { classNameProps: classNameProps, data: meta?.data, id: id })] }), tertiary ? (_jsx("div", { className: componentClassNames?.tertiary, children: tertiary })) : null, _jsx(ListItemSecondary, { classNameProps: classNameProps, classNames: classNames, data: secondary?.data, variant: variant })] }) }) }));
27
+ }
28
+ export default ListItem;
@@ -0,0 +1,11 @@
1
+ import type { ClassNameProps } from '../../../styles/interfaces';
2
+ import type { ListItemObject } from '../interfaces';
3
+ export interface ListItemMetaClassNames {
4
+ root: string;
5
+ row: string;
6
+ title: string;
7
+ value: string;
8
+ }
9
+ export type ListItemMetaProps = ClassNameProps<ListItemMetaClassNames> & ListItemObject['meta'];
10
+ declare function ListItemMeta({ classNameProps, classNames, id, data, }: Readonly<ListItemMetaProps>): React.ReactElement | null;
11
+ export default ListItemMeta;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { isValidElement } from 'react';
3
+ import { filterNull } from '@sqrzro/utility';
4
+ import { getClassNames } from '../../../styles/config';
5
+ import tw from '../../../styles/tw';
6
+ function getKey(item) {
7
+ if (isValidElement(item)) {
8
+ return item.key || '-';
9
+ }
10
+ if (typeof item === 'object') {
11
+ return JSON.stringify(item);
12
+ }
13
+ return String(item);
14
+ }
15
+ function ListItemMeta({ classNameProps, classNames, id, data, }) {
16
+ const componentClassNames = classNames || getClassNames('listItemMeta')?.(classNameProps);
17
+ if (!data) {
18
+ return null;
19
+ }
20
+ return Array.isArray(data) ? (_jsx("ul", { className: tw(componentClassNames?.root), children: filterNull(data).map((item) => (_jsx("li", { className: "whitespace-nowrap", children: item }, getKey(item)))) })) : (_jsx("table", { className: "w-full", children: _jsx("tbody", { children: Object.entries(data).map(([key, value]) => (_jsxs("tr", { className: componentClassNames?.row, children: [_jsx("th", { className: componentClassNames?.title, children: key }), _jsx("td", { className: componentClassNames?.value, children: value || '-' })] }, key))) }) }));
21
+ }
22
+ export default ListItemMeta;
@@ -0,0 +1,6 @@
1
+ import type { ClassNameProps } from '../../../styles/interfaces';
2
+ import type { ListItemClassNames } from '../ListItem';
3
+ import type { ListItemObject } from '../interfaces';
4
+ export type ListItemSecondaryProps = ClassNameProps<ListItemClassNames> & ListItemObject['secondary'];
5
+ declare function ListItemSecondary({ classNameProps, classNames, data, variant, }: Readonly<ListItemSecondaryProps>): React.ReactElement | null;
6
+ export default ListItemSecondary;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { isValidElement } from 'react';
3
+ import { getClassNames } from '../../../styles/config';
4
+ import tw from '../../../styles/tw';
5
+ import ListItemMeta from '../ListItemMeta';
6
+ function ListItemSecondary({ classNameProps, classNames, data, variant, }) {
7
+ const componentClassNames = classNames || getClassNames('listItem')?.(classNameProps);
8
+ if (!data) {
9
+ return null;
10
+ }
11
+ if (isValidElement(data)) {
12
+ return _jsx("div", { className: componentClassNames?.secondary, children: data });
13
+ }
14
+ return (_jsxs("div", { className: componentClassNames?.secondary, children: [data.title ? (_jsx("p", { className: tw(componentClassNames?.title?.default, variant ? componentClassNames?.title?.[variant] : null), children: data.title })) : null, data.description ? (_jsx("div", { className: componentClassNames?.description, children: data.description })) : null, _jsx(ListItemMeta, { classNameProps: { ...classNameProps, isSecondary: true }, data: data.meta?.data, id: "secondary" })] }));
15
+ }
16
+ export default ListItemSecondary;
@@ -0,0 +1,19 @@
1
+ import type { ClassNameProps, HighlightableClassName } from '../../../styles/interfaces';
2
+ export interface PaginationClassNames {
3
+ gap: string;
4
+ item: string;
5
+ link: HighlightableClassName;
6
+ list: string;
7
+ navigation: string;
8
+ root: string;
9
+ }
10
+ export interface PaginationProps extends ClassNameProps<PaginationClassNames> {
11
+ gapLabel?: string;
12
+ limit: number;
13
+ nextLabel?: string;
14
+ page: number;
15
+ previousLabel?: string;
16
+ total: number;
17
+ }
18
+ declare function Pagination({ classNames, classNameProps, gapLabel, limit, nextLabel, page, previousLabel, total, }: Readonly<PaginationProps>): React.ReactElement | null;
19
+ export default Pagination;
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import usePagination from '../../../hooks/usePagination';
4
+ import { getClassNames } from '../../../styles/config';
5
+ import tw from '../../../styles/tw';
6
+ import Link from '../../../components/utility/Link';
7
+ function Pagination({ classNames, classNameProps, gapLabel = '•••', limit, nextLabel, page, previousLabel, total, }) {
8
+ const componentClassNames = classNames || getClassNames('pagination')?.(classNameProps);
9
+ const { links, nextLink, pageCount, previousLink } = usePagination({ limit, page, total });
10
+ if (pageCount <= 1) {
11
+ return null;
12
+ }
13
+ return (_jsxs("nav", { className: tw(componentClassNames?.root), children: [previousLabel ? (_jsx(Link, { className: tw(componentClassNames?.navigation, page <= 1 ? 'pointer-events-none opacity-30' : null), href: previousLink, children: previousLabel })) : null, _jsx("ul", { className: tw(componentClassNames?.list), children: links.map((link, index) => (_jsx("li", { className: componentClassNames?.item, children: link ? (_jsx(Link, { className: tw(componentClassNames?.link?.default, link.label === page.toString()
14
+ ? componentClassNames?.link?.highlighted
15
+ : null), href: link.href, children: link.label })) : (_jsx("span", { className: tw(componentClassNames?.gap), children: gapLabel })) }, index))) }), nextLabel ? (_jsx(Link, { className: tw(componentClassNames?.navigation, page >= pageCount ? 'pointer-events-none opacity-30' : null), href: nextLink, children: nextLabel })) : null] }));
16
+ }
17
+ export default Pagination;
@@ -0,0 +1,9 @@
1
+ import { CollectionProps } from '../Collection';
2
+ import type { TableColumnObject, TableItemObject } from '../interfaces';
3
+ export type { TableClassNames } from '../TableClientComponent';
4
+ export interface TableProps<Item, Filters = null> extends CollectionProps<Item, TableItemObject, Filters> {
5
+ readonly columns: TableColumnObject[];
6
+ readonly isSelectable?: boolean;
7
+ }
8
+ declare function Table<Item extends object, Filters>({ columns, isSelectable, ...props }: TableProps<Item, Filters>): React.ReactElement;
9
+ export default Table;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Collection from '../Collection';
3
+ import TableClientComponent from '../TableClientComponent';
4
+ function defaultTransformer(item) {
5
+ return {
6
+ id: 'id' in item ? String(item.id) : JSON.stringify(item),
7
+ ...item,
8
+ };
9
+ }
10
+ function Table({ columns, isSelectable, ...props }) {
11
+ return (_jsx(Collection, { ...props, render: (data) => (_jsx(TableClientComponent, { columns: columns, data: data, isSelectable: isSelectable })), transformer: props.transformer ?? defaultTransformer }));
12
+ }
13
+ export default Table;
@@ -0,0 +1,14 @@
1
+ import { ClassNameProps, SelectableClassName } from '../../../styles/interfaces';
2
+ import type { TableColumnObject, TableItemObject } from '../interfaces';
3
+ export interface TableClassNames {
4
+ root: string;
5
+ row: SelectableClassName;
6
+ cell: string;
7
+ }
8
+ interface TableClientComponentProps extends ClassNameProps<TableClassNames> {
9
+ readonly columns: TableColumnObject[];
10
+ readonly data: TableItemObject[];
11
+ readonly isSelectable?: boolean;
12
+ }
13
+ declare function TableClientComponent({ classNameProps, classNames, columns, data, isSelectable, }: Readonly<TableClientComponentProps>): React.ReactElement;
14
+ export default TableClientComponent;
@@ -0,0 +1,30 @@
1
+ 'use client';
2
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
+ import { toggleArrayItem } from '@sqrzro/utility';
4
+ import { useSearchParams } from 'next/navigation';
5
+ import Switch from '../../../forms/components/Switch';
6
+ import useSearchParamsHref from '../../../hooks/useSearchParamsHref';
7
+ import { getClassNames } from '../../../styles/config';
8
+ import tw from '../../../styles/tw';
9
+ import filterColumns from '../utility/filter-columns';
10
+ import getSelectedFromSearchParams from '../utility/get-selected-from-search-params';
11
+ import setSelectedToSearchParams from '../utility/set-selected-to-search-params';
12
+ function TableClientComponent({ classNameProps, classNames, columns, data, isSelectable, }) {
13
+ const componentClassNames = classNames || getClassNames('table')?.(classNameProps);
14
+ const { setSearchParamsHref } = useSearchParamsHref();
15
+ const searchParams = useSearchParams();
16
+ const filteredColumns = filterColumns(columns, isSelectable);
17
+ const selected = getSelectedFromSearchParams(searchParams);
18
+ function handleSelect(event) {
19
+ const value = toggleArrayItem(selected, event.target.name);
20
+ setSearchParamsHref({ selected: setSelectedToSearchParams(value) });
21
+ }
22
+ function handleSelectAll() {
23
+ const value = selected.length === data.length ? [] : data.map((item) => item.id);
24
+ setSearchParamsHref({ selected: setSelectedToSearchParams(value) });
25
+ }
26
+ return (_jsx("div", { className: componentClassNames?.root, children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { children: _jsx("tr", { children: filteredColumns.map((column) => (_jsx("th", { children: column.type === 'selectable' ? (_jsxs("button", { name: column.id, onClick: handleSelectAll, children: ["Select All ", selected.includes(column.id) ? '✓' : ''] })) : (column.title) }, column.id))) }) }), _jsx("tbody", { children: data.map((item) => (_jsx("tr", { className: tw(componentClassNames?.row?.default, selected.includes(item.id)
27
+ ? componentClassNames?.row?.selected
28
+ : null), children: filteredColumns.map((column) => (_jsx("td", { className: tw(componentClassNames?.cell, column.type === 'selectable' ? 'w-1' : null), children: column.type === 'selectable' ? (_jsx(Switch, { name: item.id, onChange: handleSelect, value: selected.includes(item.id) })) : (item[column.id]) }, column.id))) }, item.id))) })] }) }));
29
+ }
30
+ export default TableClientComponent;