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

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 (193) hide show
  1. package/dist/components/buttons/ActionButton/index.d.ts +6 -6
  2. package/dist/components/buttons/ActionButton/index.js +3 -27
  3. package/dist/components/buttons/Button/index.d.ts +5 -5
  4. package/dist/components/buttons/Button/index.js +5 -14
  5. package/dist/components/collections/Collection/index.d.ts +9 -3
  6. package/dist/components/collections/Collection/index.js +4 -4
  7. package/dist/components/collections/DataTable/index.d.ts +14 -0
  8. package/dist/components/collections/DataTable/index.js +9 -0
  9. package/dist/components/collections/EmptyMessage/index.d.ts +1 -1
  10. package/dist/components/collections/EmptyMessage/index.js +3 -4
  11. package/dist/components/collections/EmptyMessageAction/index.d.ts +2 -2
  12. package/dist/components/collections/EmptyMessageAction/index.js +1 -1
  13. package/dist/components/collections/List/index.d.ts +5 -3
  14. package/dist/components/collections/List/index.js +8 -2
  15. package/dist/components/collections/ListItem/index.d.ts +2 -2
  16. package/dist/components/collections/ListItem/index.js +6 -10
  17. package/dist/components/collections/ListItemMenu/index.d.ts +7 -0
  18. package/dist/components/collections/ListItemMenu/index.js +7 -0
  19. package/dist/components/collections/ListItemMeta/index.d.ts +6 -4
  20. package/dist/components/collections/ListItemMeta/index.js +12 -7
  21. package/dist/components/collections/ListItemSecondary/index.d.ts +1 -1
  22. package/dist/components/collections/ListItemSecondary/index.js +3 -4
  23. package/dist/components/collections/Pagination/index.d.ts +1 -1
  24. package/dist/components/collections/Pagination/index.js +5 -6
  25. package/dist/components/collections/PaginationLink/index.d.ts +9 -0
  26. package/dist/components/collections/PaginationLink/index.js +8 -0
  27. package/dist/components/collections/Table/index.d.ts +3 -3
  28. package/dist/components/collections/Table/index.js +1 -1
  29. package/dist/components/collections/TableClientComponent/index.d.ts +4 -4
  30. package/dist/components/collections/TableClientComponent/index.js +5 -10
  31. package/dist/components/collections/TableRow/index.d.ts +13 -0
  32. package/dist/components/collections/TableRow/index.js +9 -0
  33. package/dist/components/collections/interfaces.d.ts +19 -17
  34. package/dist/components/collections/utility/is-data-table-array.d.ts +3 -0
  35. package/dist/components/collections/utility/is-data-table-array.js +5 -0
  36. package/dist/components/collections/utility/is-data-table-object.d.ts +3 -0
  37. package/dist/components/collections/utility/is-data-table-object.js +4 -0
  38. package/dist/components/errors/AppError/index.d.ts +19 -0
  39. package/dist/components/errors/AppError/index.js +8 -0
  40. package/dist/components/errors/AppForbiddenError/index.d.ts +7 -0
  41. package/dist/components/errors/AppForbiddenError/index.js +6 -0
  42. package/dist/components/errors/AppNotFoundError/index.d.ts +7 -0
  43. package/dist/components/errors/AppNotFoundError/index.js +6 -0
  44. package/dist/components/errors/AppServerError/index.d.ts +8 -0
  45. package/dist/components/errors/AppServerError/index.js +17 -0
  46. package/dist/components/index.d.ts +19 -0
  47. package/dist/components/index.js +9 -0
  48. package/dist/components/modals/ConfirmModal/index.d.ts +3 -1
  49. package/dist/components/modals/ConfirmModal/index.js +3 -3
  50. package/dist/components/modals/Modal/index.d.ts +4 -4
  51. package/dist/components/modals/Modal/index.js +3 -3
  52. package/dist/components/modals/ModalActions/index.d.ts +3 -3
  53. package/dist/components/modals/ModalActions/index.js +3 -3
  54. package/dist/components/utility/Action/index.d.ts +11 -0
  55. package/dist/components/utility/Action/index.js +44 -0
  56. package/dist/components/utility/ActionList/index.d.ts +3 -3
  57. package/dist/components/utility/ActionList/index.js +2 -2
  58. package/dist/components/utility/ClassNamesClientComponent/index.d.ts +6 -0
  59. package/dist/components/utility/ClassNamesClientComponent/index.js +7 -0
  60. package/dist/components/utility/Confirmable/index.d.ts +9 -0
  61. package/dist/components/utility/Confirmable/index.js +14 -0
  62. package/dist/components/utility/Container/index.d.ts +1 -1
  63. package/dist/components/utility/Container/index.js +2 -2
  64. package/dist/components/utility/Link/index.d.ts +1 -1
  65. package/dist/components/utility/Link/index.js +3 -3
  66. package/dist/components/utility/Loader/index.d.ts +1 -1
  67. package/dist/components/utility/Loader/index.js +4 -4
  68. package/dist/components/utility/Menu/index.d.ts +11 -0
  69. package/dist/components/utility/Menu/index.js +15 -0
  70. package/dist/components/utility/MenuItem/index.d.ts +4 -0
  71. package/dist/components/utility/MenuItem/index.js +9 -0
  72. package/dist/components/utility/Popover/index.d.ts +1 -1
  73. package/dist/components/utility/Popover/index.js +4 -4
  74. package/dist/components/utility/Reference/index.d.ts +9 -0
  75. package/dist/components/utility/Reference/index.js +15 -0
  76. package/dist/components/utility/RootLayout/index.d.ts +6 -3
  77. package/dist/components/utility/RootLayout/index.js +7 -6
  78. package/dist/components/utility/Toast/index.d.ts +1 -1
  79. package/dist/components/utility/Toast/index.js +2 -2
  80. package/dist/filters/components/FilterBarClientComponent/index.d.ts +1 -1
  81. package/dist/filters/components/FilterBarClientComponent/index.js +2 -2
  82. package/dist/filters/components/FilterControl/index.d.ts +1 -1
  83. package/dist/filters/components/FilterControl/index.js +7 -4
  84. package/dist/filters/components/FilterItem/index.d.ts +1 -1
  85. package/dist/filters/components/FilterItem/index.js +2 -2
  86. package/dist/filters/components/FilterPanel/index.d.ts +1 -1
  87. package/dist/filters/filters/Filter/index.d.ts +1 -1
  88. package/dist/filters/filters/Filter/index.js +3 -4
  89. package/dist/filters/filters/SearchFilter/index.js +1 -1
  90. package/dist/filters/index.d.ts +1 -0
  91. package/dist/filters/index.js +1 -0
  92. package/dist/filters/interfaces.d.ts +2 -2
  93. package/dist/filters/utility/parse-filters.d.ts +1 -1
  94. package/dist/filters/utility/parse-filters.js +3 -2
  95. package/dist/filters/utility/transform-boolean.d.ts +1 -1
  96. package/dist/filters/utility/transform-date.d.ts +1 -1
  97. package/dist/filters/utility/transform-multi.d.ts +1 -1
  98. package/dist/forms/components/Autocomplete/index.d.ts +11 -0
  99. package/dist/forms/components/Autocomplete/index.js +37 -0
  100. package/dist/forms/components/Dropdown/index.d.ts +1 -1
  101. package/dist/forms/components/Dropdown/index.js +8 -5
  102. package/dist/forms/components/DropdownItem/index.d.ts +9 -0
  103. package/dist/forms/components/DropdownItem/index.js +8 -0
  104. package/dist/forms/components/DropdownList/index.d.ts +1 -1
  105. package/dist/forms/components/DropdownList/index.js +5 -8
  106. package/dist/forms/components/EditableForm/index.d.ts +3 -3
  107. package/dist/forms/components/EditableForm/index.js +3 -4
  108. package/dist/forms/components/EditableFormField/index.d.ts +1 -1
  109. package/dist/forms/components/EditableFormField/index.js +2 -2
  110. package/dist/forms/components/Form/index.d.ts +3 -2
  111. package/dist/forms/components/Form/index.js +5 -5
  112. package/dist/forms/components/FormError/index.d.ts +1 -1
  113. package/dist/forms/components/FormError/index.js +3 -3
  114. package/dist/forms/components/FormField/index.d.ts +4 -4
  115. package/dist/forms/components/FormField/index.js +7 -6
  116. package/dist/forms/components/FormFields/index.d.ts +9 -0
  117. package/dist/forms/components/FormFields/index.js +18 -0
  118. package/dist/forms/components/FormLabel/index.d.ts +1 -1
  119. package/dist/forms/components/FormLabel/index.js +3 -3
  120. package/dist/forms/components/ModalForm/index.js +1 -1
  121. package/dist/forms/components/NumberInput/index.d.ts +7 -0
  122. package/dist/forms/components/NumberInput/index.js +27 -0
  123. package/dist/forms/components/PasswordComplexity/index.d.ts +9 -0
  124. package/dist/forms/components/PasswordComplexity/index.js +10 -0
  125. package/dist/forms/components/PasswordInput/index.d.ts +1 -1
  126. package/dist/forms/components/PasswordInput/index.js +4 -5
  127. package/dist/forms/components/PointsInput/index.d.ts +5 -0
  128. package/dist/forms/components/PointsInput/index.js +22 -0
  129. package/dist/forms/components/StaticTextInput/index.d.ts +2 -3
  130. package/dist/forms/components/StaticTextInput/index.js +5 -8
  131. package/dist/forms/components/Switch/index.d.ts +1 -1
  132. package/dist/forms/components/Switch/index.js +4 -4
  133. package/dist/forms/components/TextInput/index.d.ts +2 -2
  134. package/dist/forms/components/TextInput/index.js +6 -6
  135. package/dist/forms/hooks/useAutocomplete.d.ts +9 -0
  136. package/dist/forms/hooks/useAutocomplete.js +31 -0
  137. package/dist/forms/hooks/useDropdown.d.ts +2 -2
  138. package/dist/forms/hooks/useForm.d.ts +1 -1
  139. package/dist/forms/hooks/useForm.js +5 -4
  140. package/dist/forms/hooks/useModalForm.d.ts +2 -2
  141. package/dist/forms/index.d.ts +18 -2
  142. package/dist/forms/index.js +7 -2
  143. package/dist/forms/interfaces.d.ts +1 -0
  144. package/dist/hooks/index.d.ts +2 -0
  145. package/dist/hooks/index.js +2 -1
  146. package/dist/hooks/useConfirmable.d.ts +21 -0
  147. package/dist/hooks/useConfirmable.js +58 -0
  148. package/dist/hooks/usePopover.d.ts +11 -0
  149. package/dist/hooks/usePopover.js +17 -0
  150. package/dist/hooks/useServerAction.d.ts +9 -0
  151. package/dist/hooks/useServerAction.js +15 -0
  152. package/dist/navigation/components/AppNavigation/index.d.ts +2 -1
  153. package/dist/navigation/components/AppNavigation/index.js +4 -4
  154. package/dist/navigation/components/AppNavigationItem/index.d.ts +5 -3
  155. package/dist/navigation/components/AppNavigationItem/index.js +13 -6
  156. package/dist/navigation/components/Tabs/index.js +1 -4
  157. package/dist/navigation/hooks/useNavigation.d.ts +3 -3
  158. package/dist/navigation/hooks/useNavigation.js +5 -5
  159. package/dist/styles/classnames/apply-variants.d.ts +3 -0
  160. package/dist/styles/classnames/apply-variants.js +25 -0
  161. package/dist/styles/classnames/config.d.ts +69 -0
  162. package/dist/styles/classnames/index.d.ts +7 -0
  163. package/dist/styles/classnames/index.js +37 -0
  164. package/dist/styles/classnames/interfaces.d.ts +56 -0
  165. package/dist/styles/classnames/interfaces.js +1 -0
  166. package/dist/styles/classnames/utility/is-classname-object.d.ts +3 -0
  167. package/dist/styles/classnames/utility/is-classname-object.js +7 -0
  168. package/dist/styles/icons/config.d.ts +9 -0
  169. package/dist/styles/icons/config.js +1 -0
  170. package/dist/styles/icons/index.d.ts +4 -0
  171. package/dist/styles/icons/interfaces.d.ts +4 -0
  172. package/dist/styles/icons/interfaces.js +1 -0
  173. package/dist/styles/index.d.ts +2 -2
  174. package/dist/styles/index.js +1 -1
  175. package/dist/styles/styles.css +59 -0
  176. package/dist/utility/interfaces.d.ts +19 -8
  177. package/package.json +9 -4
  178. package/dist/components/buttons/ConfirmableButton/index.d.ts +0 -7
  179. package/dist/components/buttons/ConfirmableButton/index.js +0 -13
  180. package/dist/components/collections/ListClientComponent/index.d.ts +0 -7
  181. package/dist/components/collections/ListClientComponent/index.js +0 -9
  182. package/dist/components/collections/utility/filter-columns.d.ts +0 -3
  183. package/dist/components/collections/utility/filter-columns.js +0 -8
  184. package/dist/components/utility/ClassNames/index.d.ts +0 -6
  185. package/dist/components/utility/ClassNames/index.js +0 -7
  186. package/dist/styles/config.d.ts +0 -64
  187. package/dist/styles/config.js +0 -43
  188. package/dist/styles/icons.d.ts +0 -15
  189. package/dist/styles/interfaces.d.ts +0 -41
  190. /package/dist/styles/{interfaces.js → classnames/config.js} +0 -0
  191. /package/dist/styles/{tw.d.ts → classnames/tw.d.ts} +0 -0
  192. /package/dist/styles/{tw.js → classnames/tw.js} +0 -0
  193. /package/dist/styles/{icons.js → icons/index.js} +0 -0
@@ -1,7 +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;
1
+ import { ActionComponentProps } from '../../../components/utility/Action';
2
+ export interface ActionButtonProps<Data extends object | null = null> extends Omit<ActionComponentProps<Data>, 'children'> {
3
+ children?: React.ReactNode;
4
+ label?: React.ReactNode;
5
+ }
6
+ declare function ActionButton<Data extends object | null = null>({ isSubmittable, ...props }: ActionButtonProps<Data>): React.ReactElement;
7
7
  export default ActionButton;
@@ -1,33 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import Button from '../../../components/buttons/Button';
4
- import ConfirmableButton from '../../../components/buttons/ConfirmableButton';
4
+ import Action from '../../../components/utility/Action';
5
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 }) }));
6
+ function ActionButton({ isSubmittable, ...props }) {
7
+ return _jsx(Action, { ...props, render: isSubmittable ? FormSubmit : Button });
32
8
  }
33
9
  export default ActionButton;
@@ -1,7 +1,7 @@
1
- import type { ClassNameProps, StylableButtonClassName } from '../../../styles/interfaces';
2
- import { ButtonVariant } from '../../../utility/interfaces';
1
+ import type { ClassNameProps } from '../../../styles/classnames/interfaces';
2
+ import type { ActionEvent, StyleVariant } from '../../../utility/interfaces';
3
3
  export interface ButtonClassNames {
4
- root: StylableButtonClassName;
4
+ root: string;
5
5
  icon: string;
6
6
  }
7
7
  export interface ButtonProps extends ClassNameProps<ButtonClassNames> {
@@ -30,7 +30,7 @@ export interface ButtonProps extends ClassNameProps<ButtonClassNames> {
30
30
  /** Used in situations where the button needs to be identified by name */
31
31
  readonly name?: string;
32
32
  /** An event handler for when the button is clicked */
33
- readonly onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLButtonElement>;
33
+ readonly onClick?: (event?: ActionEvent) => void;
34
34
  /** If specified, a Popover component can be anchored to the target element with this ID */
35
35
  readonly popoverTarget?: string;
36
36
  readonly scroll?: boolean;
@@ -40,7 +40,7 @@ export interface ButtonProps extends ClassNameProps<ButtonClassNames> {
40
40
  /** Used in situations where a button value needs to be submitted with a form */
41
41
  readonly value?: string;
42
42
  /** A set of predefined variants that can be passed to the classNames config to customize the button's appearance */
43
- readonly variant?: ButtonVariant;
43
+ readonly variant?: StyleVariant[] | StyleVariant;
44
44
  }
45
45
  /**
46
46
  * Either a `Link` component or a `button` element, depending on whether a `href` prop is specified.
@@ -3,14 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useRef } from 'react';
4
4
  import Link from '../../../components/utility/Link';
5
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
- }
6
+ import { getClassNames } from '../../../styles/classnames';
7
+ import applyVariants from '../../../styles/classnames/apply-variants';
8
+ import tw from '../../../styles/classnames/tw';
14
9
  /**
15
10
  * Either a `Link` component or a `button` element, depending on whether a `href` prop is specified.
16
11
  *
@@ -32,12 +27,8 @@ function getVariantClassName(className, variant) {
32
27
  */
33
28
  function Button({ children, classNames, classNameProps, form, hasAssistiveLabel, href, icon, id, isDisabled, isFullWidth, isLoading, isNewWindow, isText, name, onClick, popoverTarget, scroll, style, type, value, variant, }) {
34
29
  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));
30
+ const componentClassNames = getClassNames(isText ? 'textButton' : 'button', { props: { ...classNameProps, ...applyVariants(variant) } }, classNames);
31
+ 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);
41
32
  /*
42
33
  * Link uses classNames, whereas button uses className. This is because Link can also be used
43
34
  * headless in other applications, and so should have consistency.
@@ -2,14 +2,20 @@ import type { FilterMap } from '../../../filters/interfaces';
2
2
  import type { NextPageProps } from '../../../utility/interfaces';
3
3
  import type { EmptyMessageProps } from '../EmptyMessage';
4
4
  import type { ListFunctionConfig, Paginated } from '../interfaces';
5
- export interface CollectionProps<Item, Transformed, Filters = null> {
5
+ export interface CollectionComponentProps<Item, Transformed, Filters = null> {
6
6
  readonly data?: Item[] | Paginated<Item>;
7
+ readonly defaultFilters?: Partial<Filters>;
7
8
  readonly emptyMessageProps?: EmptyMessageProps;
8
9
  readonly filterMap?: FilterMap<Filters>;
9
10
  readonly fn?: (config: ListFunctionConfig<Filters>) => Promise<Item[]> | Promise<Paginated<Item>>;
10
11
  readonly pageProps?: NextPageProps;
11
- readonly render: (data: Transformed[]) => React.ReactElement;
12
+ readonly renderFilters?: (props: {
13
+ map: FilterMap<Filters>;
14
+ }) => React.ReactElement;
12
15
  readonly transformer: (item: Item) => Transformed;
13
16
  }
14
- declare function Collection<Item extends object, Transformed, Filters>({ filterMap, ...props }: CollectionProps<Item, Transformed, Filters>): React.ReactElement;
17
+ export interface CollectionProps<Item, Transformed, Filters = null> extends CollectionComponentProps<Item, Transformed, Filters> {
18
+ readonly render: (data: Transformed[]) => React.ReactElement;
19
+ }
20
+ declare function Collection<Item extends object, Transformed, Filters>({ filterMap, renderFilters, ...props }: CollectionProps<Item, Transformed, Filters>): React.ReactElement;
15
21
  export default Collection;
@@ -10,7 +10,7 @@ import EmptyMessage from '../EmptyMessage';
10
10
  import Pagination from '../Pagination';
11
11
  import isPaginated from '../utility/is-paginated';
12
12
  import { messages } from '../lang';
13
- async function CollectionComponent({ data, emptyMessageProps, filterMap, fn, pageProps, render, transformer, }) {
13
+ async function CollectionComponent({ data, defaultFilters, emptyMessageProps, filterMap, fn, pageProps, render, transformer, }) {
14
14
  const EmptyIcon = getIcon('collection.empty');
15
15
  const awaitedParams = pageProps?.params ? await pageProps.params : null;
16
16
  const awaitedSearchParams = pageProps?.searchParams ? await pageProps.searchParams : null;
@@ -23,7 +23,7 @@ async function CollectionComponent({ data, emptyMessageProps, filterMap, fn, pag
23
23
  }
24
24
  const filters = parseFilters(awaitedSearchParams, filterMap);
25
25
  const page = parsePage(awaitedSearchParams);
26
- return fn({ filters, page, params: awaitedParams });
26
+ return fn({ filters: { ...defaultFilters, ...filters }, page, params: awaitedParams });
27
27
  }
28
28
  const response = await getResponse();
29
29
  const dynamicData = (isPaginated(response) ? response.data : response).map(transformer);
@@ -39,7 +39,7 @@ async function CollectionComponent({ data, emptyMessageProps, filterMap, fn, pag
39
39
  }
40
40
  return (_jsxs(Fragment, { children: [render(dynamicData), isPaginated(response) ? (_jsx(Pagination, { ...response.meta, nextLabel: "Next \u2192", previousLabel: "\u2190 Previous" })) : null] }));
41
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 }) })] }));
42
+ function Collection({ filterMap, renderFilters = FilterBar, ...props }) {
43
+ return (_jsxs(Fragment, { children: [filterMap ? renderFilters({ map: filterMap }) : null, _jsx(Suspense, { fallback: _jsx("div", { className: "flex justify-center p-16", children: _jsx(Loader, {}) }), children: _jsx(CollectionComponent, { ...props, filterMap: filterMap }) })] }));
44
44
  }
45
45
  export default Collection;
@@ -0,0 +1,14 @@
1
+ import type { ClassNameProps } from '../../../styles/classnames/interfaces';
2
+ import type { DataTableObject } from '../interfaces';
3
+ export interface DataTableClassNames {
4
+ root: string;
5
+ row: string;
6
+ cell: string;
7
+ label: string;
8
+ value: string;
9
+ }
10
+ export interface DataTableProps extends ClassNameProps<DataTableClassNames> {
11
+ readonly data: (DataTableObject | null)[];
12
+ }
13
+ declare function DataTable({ classNameProps, classNames, data }: DataTableProps): React.ReactElement;
14
+ export default DataTable;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { filterNull } from '@sqrzro/utility';
3
+ import { getClassNames } from '../../../styles/classnames';
4
+ import tw from '../../../styles/classnames/tw';
5
+ function DataTable({ classNameProps, classNames, data }) {
6
+ const componentClassNames = getClassNames('dataTable', { props: classNameProps }, classNames);
7
+ return (_jsx("table", { className: tw('w-full', componentClassNames?.root), children: _jsx("tbody", { children: filterNull(data).map(({ label, value }, index) => (_jsxs("tr", { className: componentClassNames?.row, children: [_jsx("th", { className: tw(componentClassNames?.cell, componentClassNames?.label), children: label }), _jsx("td", { className: tw(componentClassNames?.cell, componentClassNames?.value), children: value })] }, index))) }) }));
8
+ }
9
+ export default DataTable;
@@ -1,4 +1,4 @@
1
- import type { ClassNameProps, StylableClassName } from '../../../styles/interfaces';
1
+ import type { ClassNameProps, StylableClassName } from '../../../styles/classnames/interfaces';
2
2
  import { StyleVariant } from '../../../utility/interfaces';
3
3
  import type { EmptyMessageActionProps } from '../EmptyMessageAction';
4
4
  export interface EmptyMessageClassNames {
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { getClassNames } from '../../../styles/config';
4
- import tw from '../../../styles/tw';
3
+ import { getClassNames } from '../../../styles/classnames';
5
4
  import EmptyMessageAction from '../EmptyMessageAction';
6
5
  export const DEFAULT_TITLE = 'No results found';
7
6
  export const DEFAULT_CHILDREN = 'If you think this is an error, please contact the site administrator.';
@@ -11,7 +10,7 @@ export const DEFAULT_CHILDREN = 'If you think this is an error, please contact t
11
10
  * component to be used for any situation where a standout message is required.
12
11
  */
13
12
  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] }));
13
+ const componentClassNames = getClassNames('emptyMessage', { props: classNameProps }, classNames);
14
+ return (_jsxs("section", { className: componentClassNames?.root, children: [icon ? _jsx("div", { className: componentClassNames?.icon, children: icon }) : null, _jsx("h2", { className: componentClassNames?.title, children: title }), _jsx("div", { className: componentClassNames?.description, children: children }), action ? (_jsx("div", { className: componentClassNames?.action, children: _jsx(EmptyMessageAction, { action: action }) })) : null] }));
16
15
  }
17
16
  export default EmptyMessage;
@@ -1,6 +1,6 @@
1
- import { Action } from '../../../utility/interfaces';
1
+ import { ActionObject } from '../../../utility/interfaces';
2
2
  export interface EmptyMessageActionProps {
3
- action: Action | React.ReactElement;
3
+ action: ActionObject | React.ReactElement;
4
4
  }
5
5
  declare function EmptyMessageAction({ action }: Readonly<EmptyMessageActionProps>): React.ReactElement;
6
6
  export default EmptyMessageAction;
@@ -13,7 +13,7 @@ function EmptyMessageAction({ action }) {
13
13
  action.onClick();
14
14
  }
15
15
  }
16
- const href = action.action ? getSearchParamsHref('action', action.action) : action.href;
16
+ const href = action.searchParams ? getSearchParamsHref(action.searchParams) : action.href;
17
17
  return (_jsx(Button, { href: href, isDisabled: Boolean(action.isDisabled), onClick: handleClick, variant: "primary", children: action.label }));
18
18
  }
19
19
  export default EmptyMessageAction;
@@ -1,6 +1,8 @@
1
- import { CollectionProps } from '../Collection';
1
+ import { CollectionComponentProps } from '../Collection';
2
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'> {
3
+ export interface ListClassNames {
4
+ root: string;
4
5
  }
5
- declare function List<Item extends object, Filters, Data extends object | null = null>(props: ListProps<Item, Filters, Data>): React.ReactElement;
6
+ export type ListProps<Item, Filters = null, Data extends object | null = null> = CollectionComponentProps<Item, ListItemObject<Data>, Filters>;
7
+ declare function List<Item extends object, Filters = null, Data extends object | null = null>(props: ListProps<Item, Filters, Data>): React.ReactElement;
6
8
  export default List;
@@ -1,13 +1,19 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import { getClassNames } from '../../../styles/classnames';
2
4
  import Collection from '../Collection';
3
- import ListClientComponent from '../ListClientComponent';
5
+ import ListItem from '../ListItem';
4
6
  function defaultTransformer(item) {
5
7
  return {
6
8
  id: 'id' in item ? String(item.id) : JSON.stringify(item),
7
9
  title: 'title' in item ? String(item.title) : '',
8
10
  };
9
11
  }
12
+ function ListComponent({ classNameProps, classNames, data, renderItem = ListItem, }) {
13
+ const componentClassNames = getClassNames('list', { props: classNameProps }, classNames);
14
+ return (_jsx("ul", { className: componentClassNames?.root, children: data.map((item) => (_jsx(Fragment, { children: renderItem(item) }, item.id))) }));
15
+ }
10
16
  function List(props) {
11
- return (_jsx(Collection, { ...props, render: (data) => _jsx(ListClientComponent, { data: data }), transformer: props.transformer ?? defaultTransformer }));
17
+ return (_jsx(Collection, { ...props, render: (data) => _jsx(ListComponent, { data: data }), transformer: props.transformer ?? defaultTransformer }));
12
18
  }
13
19
  export default List;
@@ -1,4 +1,4 @@
1
- import type { ClassNameProps, StylableClassName } from '../../../styles/interfaces';
1
+ import type { ClassNameProps, StylableClassName } from '../../../styles/classnames/interfaces';
2
2
  import type { ListItemObject } from '../interfaces';
3
3
  export interface ListItemClassNames {
4
4
  description: string;
@@ -10,5 +10,5 @@ export interface ListItemClassNames {
10
10
  }
11
11
  export interface ListItemProps<Data extends object | null = null> extends ClassNameProps<ListItemClassNames>, ListItemObject<Data> {
12
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;
13
+ declare function ListItem<Data extends object | null = null>({ $data, actions, classNames, classNameProps, description, href, id, isLoading, meta, secondary, tertiary, title, variant, }: Readonly<ListItemProps<Data>>): React.ReactElement;
14
14
  export default ListItem;
@@ -1,10 +1,10 @@
1
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';
2
+ import { getClassNames } from '../../../styles/classnames';
3
+ import tw from '../../../styles/classnames/tw';
5
4
  import Link from '../../../components/utility/Link';
6
5
  import ListItemSecondary from '../ListItemSecondary';
7
6
  import ListItemMeta from '../ListItemMeta';
7
+ import ListItemMenu from '../ListItemMenu';
8
8
  const colMap = {
9
9
  1: 'grid-cols-1',
10
10
  2: 'grid-cols-1 @lg:grid-cols-[1fr_1fr]',
@@ -14,15 +14,11 @@ function getLayout(layout) {
14
14
  const count = layout.filter(Boolean).length;
15
15
  return colMap[count];
16
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);
17
+ function ListItem({ $data, actions, classNames, classNameProps, description, href, id, isLoading, meta, secondary, tertiary, title, variant, }) {
18
+ const componentClassNames = getClassNames('listItem', { props: classNameProps }, classNames);
21
19
  const hasPrimary = Boolean(title || description || meta);
22
20
  const hasSecondary = Boolean(secondary);
23
21
  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 })] }) }) }));
22
+ return (_jsx("li", { className: tw('@container relative grid', componentClassNames?.root, isLoading ? 'pointer-events-none animate-pulse' : null, actions ? 'grid-cols-[1fr_auto] gap-4' : 'grid-cols-1'), children: _jsxs("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: componentClassNames?.title, 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 })] }), tertiary ? (_jsx("div", { className: componentClassNames?.tertiary, children: tertiary })) : null, _jsx(ListItemSecondary, { classNameProps: classNameProps, classNames: classNames, data: secondary?.data, variant: variant })] }), actions ? _jsx(ListItemMenu, { actions: actions, data: $data }) : null] }) }));
27
23
  }
28
24
  export default ListItem;
@@ -0,0 +1,7 @@
1
+ import type { ActionObject } from '../../../utility/interfaces';
2
+ interface ListItemMenuProps<Data extends object | null = null> {
3
+ actions: ActionObject<Data>[];
4
+ data?: Data;
5
+ }
6
+ declare function ListItemMenu<Data extends object | null = null>({ actions, data, }: ListItemMenuProps<Data>): React.ReactElement;
7
+ export default ListItemMenu;
@@ -0,0 +1,7 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import Menu from '../../../components/utility/Menu';
4
+ function ListItemMenu({ actions, data, }) {
5
+ return _jsx(Menu, { actions: actions, data: data, label: "\u2022\u2022\u2022" });
6
+ }
7
+ export default ListItemMenu;
@@ -1,11 +1,13 @@
1
- import type { ClassNameProps } from '../../../styles/interfaces';
2
- import type { ListItemObject } from '../interfaces';
1
+ import type { ClassNameProps } from '../../../styles/classnames/interfaces';
2
+ import type { DataTableObject } from '../interfaces';
3
3
  export interface ListItemMetaClassNames {
4
4
  root: string;
5
5
  row: string;
6
6
  title: string;
7
7
  value: string;
8
8
  }
9
- export type ListItemMetaProps = ClassNameProps<ListItemMetaClassNames> & ListItemObject['meta'];
10
- declare function ListItemMeta({ classNameProps, classNames, id, data, }: Readonly<ListItemMetaProps>): React.ReactElement | null;
9
+ export type ListItemMetaProps = ClassNameProps<ListItemMetaClassNames> & {
10
+ data?: React.ReactNode[] | (DataTableObject | null)[];
11
+ };
12
+ declare function ListItemMeta({ classNameProps, classNames, data, }: Readonly<ListItemMetaProps>): React.ReactElement | null;
11
13
  export default ListItemMeta;
@@ -1,8 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { isValidElement } from 'react';
3
3
  import { filterNull } from '@sqrzro/utility';
4
- import { getClassNames } from '../../../styles/config';
5
- import tw from '../../../styles/tw';
4
+ import { getClassNames } from '../../../styles/classnames';
5
+ import DataTable from '../DataTable';
6
+ import isDataTableArray from '../utility/is-data-table-array';
6
7
  function getKey(item) {
7
8
  if (isValidElement(item)) {
8
9
  return item.key || '-';
@@ -12,11 +13,15 @@ function getKey(item) {
12
13
  }
13
14
  return String(item);
14
15
  }
15
- function ListItemMeta({ classNameProps, classNames, id, data, }) {
16
- const componentClassNames = classNames || getClassNames('listItemMeta')?.(classNameProps);
17
- if (!data) {
16
+ function ListItemMeta({ classNameProps, classNames, data, }) {
17
+ const componentClassNames = getClassNames('listItemMeta', { props: classNameProps }, classNames);
18
+ if (!data?.length) {
18
19
  return null;
19
20
  }
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
+ const filteredData = filterNull(data);
22
+ if (isDataTableArray(filteredData)) {
23
+ return _jsx(DataTable, { data: filteredData });
24
+ }
25
+ return (_jsx("ul", { className: componentClassNames?.root, children: filteredData.map((item) => (_jsx("li", { className: "whitespace-nowrap", children: item }, getKey(item)))) }));
21
26
  }
22
27
  export default ListItemMeta;
@@ -1,4 +1,4 @@
1
- import type { ClassNameProps } from '../../../styles/interfaces';
1
+ import type { ClassNameProps } from '../../../styles/classnames/interfaces';
2
2
  import type { ListItemClassNames } from '../ListItem';
3
3
  import type { ListItemObject } from '../interfaces';
4
4
  export type ListItemSecondaryProps = ClassNameProps<ListItemClassNames> & ListItemObject['secondary'];
@@ -1,16 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { isValidElement } from 'react';
3
- import { getClassNames } from '../../../styles/config';
4
- import tw from '../../../styles/tw';
3
+ import { getClassNames } from '../../../styles/classnames';
5
4
  import ListItemMeta from '../ListItemMeta';
6
5
  function ListItemSecondary({ classNameProps, classNames, data, variant, }) {
7
- const componentClassNames = classNames || getClassNames('listItem')?.(classNameProps);
6
+ const componentClassNames = getClassNames('listItem', { props: classNameProps }, classNames);
8
7
  if (!data) {
9
8
  return null;
10
9
  }
11
10
  if (isValidElement(data)) {
12
11
  return _jsx("div", { className: componentClassNames?.secondary, children: data });
13
12
  }
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" })] }));
13
+ return (_jsxs("div", { className: componentClassNames?.secondary, children: [data.title ? _jsx("p", { className: componentClassNames?.title, children: data.title }) : null, data.description ? (_jsx("div", { className: componentClassNames?.description, children: data.description })) : null, _jsx(ListItemMeta, { classNameProps: { ...classNameProps, isSecondary: true }, data: data.meta })] }));
15
14
  }
16
15
  export default ListItemSecondary;
@@ -1,4 +1,4 @@
1
- import type { ClassNameProps, HighlightableClassName } from '../../../styles/interfaces';
1
+ import type { ClassNameProps, HighlightableClassName } from '../../../styles/classnames/interfaces';
2
2
  export interface PaginationClassNames {
3
3
  gap: string;
4
4
  item: string;
@@ -1,17 +1,16 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import usePagination from '../../../hooks/usePagination';
4
- import { getClassNames } from '../../../styles/config';
5
- import tw from '../../../styles/tw';
4
+ import { getClassNames } from '../../../styles/classnames';
5
+ import tw from '../../../styles/classnames/tw';
6
6
  import Link from '../../../components/utility/Link';
7
+ import PaginationLink from '../PaginationLink';
7
8
  function Pagination({ classNames, classNameProps, gapLabel = '•••', limit, nextLabel, page, previousLabel, total, }) {
8
- const componentClassNames = classNames || getClassNames('pagination')?.(classNameProps);
9
+ const componentClassNames = getClassNames('pagination', { props: classNameProps }, classNames);
9
10
  const { links, nextLink, pageCount, previousLink } = usePagination({ limit, page, total });
10
11
  if (pageCount <= 1) {
11
12
  return null;
12
13
  }
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] }));
14
+ return (_jsxs("nav", { className: 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: componentClassNames?.list, children: links.map((link, index) => (_jsx("li", { className: componentClassNames?.item, children: link ? (_jsx(PaginationLink, { ...link, isCurrent: link.label === page.toString() })) : (_jsx("span", { className: 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
15
  }
17
16
  export default Pagination;
@@ -0,0 +1,9 @@
1
+ import type { ClassNameProps } from '../../../styles/classnames/interfaces';
2
+ import type { PaginationClassNames } from '../Pagination';
3
+ interface PaginationLinkProps extends ClassNameProps<PaginationClassNames> {
4
+ href: string;
5
+ isCurrent: boolean;
6
+ label: string;
7
+ }
8
+ declare function PaginationLink({ classNameProps, classNames, href, isCurrent, label, }: PaginationLinkProps): React.ReactElement;
9
+ export default PaginationLink;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Link from '../../../components/utility/Link';
3
+ import { getClassNames } from '../../../styles/classnames';
4
+ function PaginationLink({ classNameProps, classNames, href, isCurrent, label, }) {
5
+ const componentClassNames = getClassNames('pagination', { props: classNameProps, states: { isHighlighted: isCurrent } }, classNames);
6
+ return (_jsx(Link, { className: componentClassNames?.link, href: href, children: label }));
7
+ }
8
+ export default PaginationLink;
@@ -1,9 +1,9 @@
1
- import { CollectionProps } from '../Collection';
1
+ import { CollectionComponentProps } from '../Collection';
2
2
  import type { TableColumnObject, TableItemObject } from '../interfaces';
3
3
  export type { TableClassNames } from '../TableClientComponent';
4
- export interface TableProps<Item, Filters = null> extends CollectionProps<Item, TableItemObject, Filters> {
4
+ export interface TableProps<Item, Filters = null, Data extends object | null = null> extends CollectionComponentProps<Item, TableItemObject<Data>, Filters> {
5
5
  readonly columns: TableColumnObject[];
6
6
  readonly isSelectable?: boolean;
7
7
  }
8
- declare function Table<Item extends object, Filters>({ columns, isSelectable, ...props }: TableProps<Item, Filters>): React.ReactElement;
8
+ declare function Table<Item extends object, Filters = null, Data extends object | null = null>({ columns, isSelectable, ...props }: TableProps<Item, Filters, Data>): React.ReactElement;
9
9
  export default Table;
@@ -4,7 +4,7 @@ import TableClientComponent from '../TableClientComponent';
4
4
  function defaultTransformer(item) {
5
5
  return {
6
6
  id: 'id' in item ? String(item.id) : JSON.stringify(item),
7
- ...item,
7
+ row: { ...item },
8
8
  };
9
9
  }
10
10
  function Table({ columns, isSelectable, ...props }) {
@@ -1,14 +1,14 @@
1
- import { ClassNameProps, SelectableClassName } from '../../../styles/interfaces';
1
+ import { ClassNameProps, SelectableClassName } from '../../../styles/classnames/interfaces';
2
2
  import type { TableColumnObject, TableItemObject } from '../interfaces';
3
3
  export interface TableClassNames {
4
4
  root: string;
5
5
  row: SelectableClassName;
6
6
  cell: string;
7
7
  }
8
- interface TableClientComponentProps extends ClassNameProps<TableClassNames> {
8
+ interface TableClientComponentProps<Data extends object | null = null> extends ClassNameProps<TableClassNames> {
9
9
  readonly columns: TableColumnObject[];
10
- readonly data: TableItemObject[];
10
+ readonly data: TableItemObject<Data>[];
11
11
  readonly isSelectable?: boolean;
12
12
  }
13
- declare function TableClientComponent({ classNameProps, classNames, columns, data, isSelectable, }: Readonly<TableClientComponentProps>): React.ReactElement;
13
+ declare function TableClientComponent<Data extends object | null = null>({ classNameProps, classNames, columns, data, isSelectable, }: Readonly<TableClientComponentProps<Data>>): React.ReactElement;
14
14
  export default TableClientComponent;
@@ -1,19 +1,16 @@
1
1
  'use client';
2
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { toggleArrayItem } from '@sqrzro/utility';
4
4
  import { useSearchParams } from 'next/navigation';
5
- import Switch from '../../../forms/components/Switch';
6
5
  import useSearchParamsHref from '../../../hooks/useSearchParamsHref';
7
- import { getClassNames } from '../../../styles/config';
8
- import tw from '../../../styles/tw';
9
- import filterColumns from '../utility/filter-columns';
6
+ import { getClassNames } from '../../../styles/classnames';
10
7
  import getSelectedFromSearchParams from '../utility/get-selected-from-search-params';
11
8
  import setSelectedToSearchParams from '../utility/set-selected-to-search-params';
9
+ import TableRow from '../TableRow';
12
10
  function TableClientComponent({ classNameProps, classNames, columns, data, isSelectable, }) {
13
- const componentClassNames = classNames || getClassNames('table')?.(classNameProps);
11
+ const componentClassNames = getClassNames('table', { props: classNameProps }, classNames);
14
12
  const { setSearchParamsHref } = useSearchParamsHref();
15
13
  const searchParams = useSearchParams();
16
- const filteredColumns = filterColumns(columns, isSelectable);
17
14
  const selected = getSelectedFromSearchParams(searchParams);
18
15
  function handleSelect(event) {
19
16
  const value = toggleArrayItem(selected, event.target.name);
@@ -23,8 +20,6 @@ function TableClientComponent({ classNameProps, classNames, columns, data, isSel
23
20
  const value = selected.length === data.length ? [] : data.map((item) => item.id);
24
21
  setSearchParamsHref({ selected: setSelectedToSearchParams(value) });
25
22
  }
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))) })] }) }));
23
+ return (_jsx("div", { className: componentClassNames?.root, children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { children: _jsxs("tr", { children: [data[0].isSelectable ? (_jsx("th", { children: _jsx("button", { onClick: handleSelectAll, children: "Select All" }) })) : null, columns.map((column) => (_jsx("th", { children: column.title }, column.id)))] }) }), _jsx("tbody", { children: data.map((item) => (_jsx(TableRow, { columns: columns, data: item, isSelected: selected.includes(item.id), onSelect: handleSelect }, item.id))) })] }) }));
29
24
  }
30
25
  export default TableClientComponent;
@@ -0,0 +1,13 @@
1
+ import type { InputEvent } from '../../../forms/interfaces';
2
+ import type { ClassNameProps } from '../../../styles/classnames/interfaces';
3
+ import type { TableClassNames } from '../TableClientComponent';
4
+ import type { TableColumnObject, TableItemObject } from '../interfaces';
5
+ interface TableRowProps<Data extends object | null = null> extends ClassNameProps<TableClassNames> {
6
+ columns: TableColumnObject[];
7
+ data: TableItemObject<Data>;
8
+ isSelectable?: boolean;
9
+ isSelected: boolean;
10
+ onSelect: (event: InputEvent<boolean>) => void;
11
+ }
12
+ declare function TableRow<Data extends object | null = null>({ classNameProps, classNames, columns, data, isSelected, onSelect, }: TableRowProps<Data>): React.ReactElement;
13
+ export default TableRow;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Switch from '../../../forms/components/Switch';
3
+ import { getClassNames } from '../../../styles/classnames';
4
+ import ListItemMenu from '../ListItemMenu';
5
+ function TableRow({ classNameProps, classNames, columns, data, isSelected, onSelect, }) {
6
+ const componentClassNames = getClassNames('table', { props: classNameProps, states: { isSelected } }, classNames);
7
+ return (_jsxs("tr", { className: componentClassNames?.row, children: [data.isSelectable ? (_jsx("td", { children: _jsx(Switch, { name: data.id, onChange: onSelect, value: isSelected }) })) : null, columns.map((column) => (_jsx("td", { className: componentClassNames?.cell, children: data.row[column.id] }, column.id))), data.actions ? (_jsx("td", { children: _jsx(ListItemMenu, { actions: data.actions, data: data.$data }) })) : null] }));
8
+ }
9
+ export default TableRow;