mautourco-components 0.2.12 → 0.2.13

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 (133) hide show
  1. package/dist/components/atoms/Icon/Icon.d.ts +1 -1
  2. package/dist/components/atoms/Icon/Icon.js +1 -1
  3. package/dist/components/atoms/Icon/icons/AccomIcon.d.ts +12 -0
  4. package/dist/components/atoms/Icon/icons/AccomIcon.js +36 -0
  5. package/dist/components/atoms/Icon/icons/ArrowDownOutlineIcon.d.ts +8 -0
  6. package/dist/components/atoms/Icon/icons/ArrowDownOutlineIcon.js +36 -0
  7. package/dist/components/atoms/Icon/icons/ArrowRightOutlineIcon.js +1 -1
  8. package/dist/components/atoms/Icon/icons/BusIcon.d.ts +12 -0
  9. package/dist/components/atoms/Icon/icons/BusIcon.js +36 -0
  10. package/dist/components/atoms/Icon/icons/Calendar2Icon.d.ts +12 -0
  11. package/dist/components/atoms/Icon/icons/Calendar2Icon.js +36 -0
  12. package/dist/components/atoms/Icon/icons/MapIcon.d.ts +8 -0
  13. package/dist/components/atoms/Icon/icons/MapIcon.js +36 -0
  14. package/dist/components/atoms/Icon/icons/MicroIcon.d.ts +12 -0
  15. package/dist/components/atoms/Icon/icons/MicroIcon.js +36 -0
  16. package/dist/components/atoms/Icon/icons/MoreVerticalIcon.d.ts +12 -0
  17. package/dist/components/atoms/Icon/icons/MoreVerticalIcon.js +36 -0
  18. package/dist/components/atoms/Icon/icons/NightIcon.d.ts +12 -0
  19. package/dist/components/atoms/Icon/icons/NightIcon.js +36 -0
  20. package/dist/components/atoms/Icon/icons/RowExcursion.d.ts +16 -0
  21. package/dist/components/atoms/Icon/icons/RowExcursion.js +28 -0
  22. package/dist/components/atoms/Icon/icons/StopWatchIcon.d.ts +12 -0
  23. package/dist/components/atoms/Icon/icons/StopWatchIcon.js +36 -0
  24. package/dist/components/atoms/Icon/icons/Utensils.d.ts +12 -0
  25. package/dist/components/atoms/Icon/icons/Utensils.js +36 -0
  26. package/dist/components/atoms/Icon/icons/WalletIcon.d.ts +12 -0
  27. package/dist/components/atoms/Icon/icons/WalletIcon.js +36 -0
  28. package/dist/components/atoms/Icon/icons/registry.d.ts +11 -0
  29. package/dist/components/atoms/Icon/icons/registry.js +49 -27
  30. package/dist/components/atoms/Typography/Typography.d.ts +3 -1
  31. package/dist/components/atoms/Typography/Typography.js +3 -15
  32. package/dist/components/molecules/ActionDropdown/ActionDropdown.css +2119 -0
  33. package/dist/components/molecules/ActionDropdown/ActionDropdown.d.ts +21 -0
  34. package/dist/components/molecules/ActionDropdown/ActionDropdown.js +34 -0
  35. package/dist/components/molecules/DateDisplay/DateDisplay.d.ts +14 -0
  36. package/dist/components/molecules/DateDisplay/DateDisplay.js +39 -0
  37. package/dist/components/molecules/FromTo/FromTo.d.ts +8 -0
  38. package/dist/components/molecules/FromTo/FromTo.js +24 -0
  39. package/dist/components/molecules/TableServiceItem/DetailsCol.d.ts +12 -0
  40. package/dist/components/molecules/TableServiceItem/DetailsCol.js +17 -0
  41. package/dist/components/molecules/TableServiceItem/ItemCol.d.ts +13 -0
  42. package/dist/components/molecules/TableServiceItem/ItemCol.js +24 -0
  43. package/dist/components/molecules/TableServiceItem/RowAccommodation.d.ts +16 -0
  44. package/dist/components/molecules/TableServiceItem/RowAccommodation.js +37 -0
  45. package/dist/components/molecules/TableServiceItem/RowExcursion.d.ts +16 -0
  46. package/dist/components/molecules/TableServiceItem/RowExcursion.js +22 -0
  47. package/dist/components/molecules/TableServiceItem/RowOtherServices.d.ts +9 -0
  48. package/dist/components/molecules/TableServiceItem/RowOtherServices.js +34 -0
  49. package/dist/components/molecules/TableServiceItem/RowTransfer.d.ts +15 -0
  50. package/dist/components/molecules/TableServiceItem/RowTransfer.js +37 -0
  51. package/dist/components/molecules/TableServiceItem/index.d.ts +17 -0
  52. package/dist/components/molecules/TableServiceItem/index.js +15 -0
  53. package/dist/components/molecules/TextWithIcon/TextWithIcon.d.ts +30 -0
  54. package/dist/components/molecules/TextWithIcon/TextWithIcon.js +31 -0
  55. package/dist/components/molecules/TooltipDisplay/TooltipDisplay.d.ts +13 -0
  56. package/dist/components/molecules/TooltipDisplay/TooltipDisplay.js +18 -0
  57. package/dist/components/organisms/Table/Table.css +2280 -0
  58. package/dist/components/organisms/Table/Table.d.ts +50 -0
  59. package/dist/components/organisms/Table/Table.js +95 -0
  60. package/dist/components/organisms/Table/TableCell.d.ts +15 -0
  61. package/dist/components/organisms/Table/TableCell.js +16 -0
  62. package/dist/components/organisms/Table/columns/booking-columns.d.ts +7 -0
  63. package/dist/components/organisms/Table/columns/booking-columns.js +83 -0
  64. package/dist/components/organisms/Table/columns/detail-resume-columns.d.ts +3 -0
  65. package/dist/components/organisms/Table/columns/detail-resume-columns.js +178 -0
  66. package/dist/components/organisms/Table/columns/index.d.ts +12 -0
  67. package/dist/components/organisms/Table/columns/index.js +9 -0
  68. package/dist/components/organisms/Table/columns/quotation-columns.d.ts +7 -0
  69. package/dist/components/organisms/Table/columns/quotation-columns.js +91 -0
  70. package/dist/components/organisms/Table/constant.d.ts +6 -0
  71. package/dist/components/organisms/Table/constant.js +24 -0
  72. package/dist/components/organisms/Table/index.d.ts +2 -0
  73. package/dist/components/organisms/Table/index.js +2 -0
  74. package/dist/components/ui/popover.d.ts +3 -3
  75. package/dist/components/ui/popover.js +5 -5
  76. package/dist/components/ui/tooltip.d.ts +7 -0
  77. package/dist/components/ui/tooltip.js +42 -0
  78. package/dist/index.d.ts +41 -33
  79. package/dist/index.js +26 -20
  80. package/dist/styles/components/typography.css +1 -0
  81. package/dist/types/table/action-dropdown-type.types.d.ts +5 -0
  82. package/dist/types/table/action-dropdown-type.types.js +6 -0
  83. package/dist/types/table/booking.types.d.ts +16 -0
  84. package/dist/types/table/booking.types.js +1 -0
  85. package/dist/types/table/detail-resume.types.d.ts +155 -0
  86. package/dist/types/table/detail-resume.types.js +7 -0
  87. package/dist/types/table/index.d.ts +3 -0
  88. package/dist/types/table/index.js +3 -0
  89. package/dist/types/table/quotation.types.d.ts +23 -0
  90. package/dist/types/table/quotation.types.js +1 -0
  91. package/package.json +6 -1
  92. package/src/components/atoms/Icon/Icon.tsx +2 -8
  93. package/src/components/atoms/Icon/icons/AccomIcon.tsx +45 -0
  94. package/src/components/atoms/Icon/icons/ArrowDownOutlineIcon.tsx +41 -0
  95. package/src/components/atoms/Icon/icons/ArrowRightOutlineIcon.tsx +2 -7
  96. package/src/components/atoms/Icon/icons/BusIcon.tsx +52 -0
  97. package/src/components/atoms/Icon/icons/Calendar2Icon.tsx +54 -0
  98. package/src/components/atoms/Icon/icons/MapIcon.tsx +48 -0
  99. package/src/components/atoms/Icon/icons/MicroIcon.tsx +45 -0
  100. package/src/components/atoms/Icon/icons/MoreVerticalIcon.tsx +53 -0
  101. package/src/components/atoms/Icon/icons/NightIcon.tsx +45 -0
  102. package/src/components/atoms/Icon/icons/RowExcursion.tsx +54 -0
  103. package/src/components/atoms/Icon/icons/StopWatchIcon.tsx +45 -0
  104. package/src/components/atoms/Icon/icons/Utensils.tsx +45 -0
  105. package/src/components/atoms/Icon/icons/WalletIcon.tsx +45 -0
  106. package/src/components/atoms/Icon/icons/registry.tsx +50 -28
  107. package/src/components/atoms/Typography/Typography.tsx +22 -30
  108. package/src/components/molecules/ActionDropdown/ActionDropdown.css +23 -0
  109. package/src/components/molecules/ActionDropdown/ActionDropdown.tsx +53 -0
  110. package/src/components/molecules/DateDisplay/DateDisplay.tsx +47 -0
  111. package/src/components/molecules/FromTo/FromTo.tsx +31 -0
  112. package/src/components/molecules/TableServiceItem/DetailsCol.tsx +25 -0
  113. package/src/components/molecules/TableServiceItem/ItemCol.tsx +68 -0
  114. package/src/components/molecules/TableServiceItem/RowAccommodation.tsx +56 -0
  115. package/src/components/molecules/TableServiceItem/RowExcursion.tsx +40 -0
  116. package/src/components/molecules/TableServiceItem/RowOtherServices.tsx +50 -0
  117. package/src/components/molecules/TableServiceItem/RowTransfer.tsx +60 -0
  118. package/src/components/molecules/TableServiceItem/index.ts +24 -0
  119. package/src/components/molecules/TextWithIcon/TextWithIcon.tsx +62 -0
  120. package/src/components/molecules/TooltipDisplay/TooltipDisplay.tsx +32 -0
  121. package/src/components/organisms/CarBookingCard/index.ts +2 -0
  122. package/src/components/organisms/Table/Table.css +185 -0
  123. package/src/components/organisms/Table/Table.tsx +273 -0
  124. package/src/components/organisms/Table/TableCell.tsx +40 -0
  125. package/src/components/organisms/Table/columns/booking-columns.tsx +118 -0
  126. package/src/components/organisms/Table/columns/detail-resume-columns.tsx +226 -0
  127. package/src/components/organisms/Table/columns/index.ts +11 -0
  128. package/src/components/organisms/Table/columns/quotation-columns.tsx +150 -0
  129. package/src/components/organisms/Table/constant.ts +31 -0
  130. package/src/components/organisms/Table/index.ts +2 -0
  131. package/src/components/ui/popover.tsx +10 -10
  132. package/src/components/ui/tooltip.tsx +45 -0
  133. package/src/styles/components/typography.css +4 -0
@@ -0,0 +1,24 @@
1
+ import { DetailsCol, type DetailsColProps } from './DetailsCol';
2
+ import { ItemCol, type ItemColProps } from './ItemCol';
3
+ import { RowAccommodation, type RowAccommodationProps } from './RowAccommodation';
4
+ import { RowExcursion, type RowExcursionProps } from './RowExcursion';
5
+ import { RowOtherServices } from './RowOtherServices';
6
+ import { RowTransfer, type RowTransferProps } from './RowTransfer';
7
+
8
+ const TableServiceItem = {
9
+ DetailsCol,
10
+ ItemCol,
11
+ RowAccommodation,
12
+ RowExcursion,
13
+ RowOtherServices,
14
+ RowTransfer,
15
+ };
16
+
17
+ export type {
18
+ DetailsColProps,
19
+ ItemColProps,
20
+ RowAccommodationProps,
21
+ RowExcursionProps,
22
+ RowTransferProps,
23
+ };
24
+ export default TableServiceItem;
@@ -0,0 +1,62 @@
1
+ import { cn } from '@/src/lib/utils';
2
+ import Icon, { IconName } from '../../atoms/Icon/Icon';
3
+ import { Text, TextColor, TextLeading, TextVariant } from '../../atoms/Typography/Typography';
4
+
5
+ export interface TextWithIconProps {
6
+ /** Icon to display */
7
+ icon: IconName;
8
+
9
+ /** Icon size */
10
+ iconSize?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
11
+
12
+ /** Children to display */
13
+ children: React.ReactNode;
14
+
15
+ /** Color of the text */
16
+ color?: TextColor;
17
+
18
+ /** Leading of the text */
19
+ textLeading?: TextLeading;
20
+
21
+ /** Variant of the text */
22
+ textVariant?: TextVariant;
23
+ }
24
+
25
+ /**
26
+ * A component that displays a text with an icon.
27
+ *
28
+ * @example
29
+ * <TextWithIcon icon="calendar" color="yellow">
30
+ * 20/12/2025
31
+ * </TextWithIcon>
32
+ *
33
+ * @param TextWithIconProps
34
+ * @returns
35
+ */
36
+ const TextWithIcon: React.FC<TextWithIconProps> = (props) => {
37
+ const { icon, children, iconSize = 'sm', color = 'default', textLeading = '5', textVariant = 'medium' } = props;
38
+
39
+ return (
40
+ <div
41
+ className={cn(
42
+ 'flex items-center gap-x-2',
43
+ color === 'yellow' && 'text-[var(--color-yellow-600)]',
44
+ color === 'accent' && 'text-[var(--color-text-accent)]'
45
+ )}>
46
+ <span>
47
+ <Icon name={icon} size={iconSize} />
48
+ </span>
49
+ <Text
50
+ variant={textVariant}
51
+ size={iconSize}
52
+ className="flex items-center gap-x-2"
53
+ color={color}
54
+ leading={textLeading}
55
+ as="div">
56
+ {children}
57
+ </Text>
58
+ </div>
59
+ );
60
+ };
61
+
62
+ export default TextWithIcon;
@@ -0,0 +1,32 @@
1
+ import { TooltipContentProps } from '@radix-ui/react-tooltip';
2
+ import React from 'react';
3
+ import { Text } from '../../atoms/Typography/Typography';
4
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip';
5
+
6
+ export interface TooltipDisplayProps {
7
+ /** Trigger element */
8
+ children: React.ReactNode;
9
+
10
+ /** Tooltip content */
11
+ content: string;
12
+
13
+ /** Side of the tooltip */
14
+ side?: TooltipContentProps['side'];
15
+
16
+ /** Maximum width of the tooltip */
17
+ maxWidth?: `${number}px`;
18
+ }
19
+
20
+ export const TooltipDisplay: React.FC<TooltipDisplayProps> = (props) => {
21
+ const { children, content, side = 'right', maxWidth = '300px' } = props;
22
+ return (
23
+ <Tooltip>
24
+ <TooltipTrigger className="text-[var(--color-icon-branded)]">{children}</TooltipTrigger>
25
+ <TooltipContent className={`max-w-[${maxWidth}]`} side={side}>
26
+ <Text variant="medium" size="sm" className="!text-white">
27
+ {content}
28
+ </Text>
29
+ </TooltipContent>
30
+ </Tooltip>
31
+ );
32
+ };
@@ -10,3 +10,5 @@ export type {
10
10
 
11
11
 
12
12
 
13
+
14
+
@@ -0,0 +1,185 @@
1
+ .table-container {
2
+ overflow-y: hidden;
3
+ overflow-x: auto;
4
+ max-width: 1680px;
5
+ &.table-container--no-total {
6
+ padding-bottom: var(--spacing-padding-px-4);
7
+ }
8
+ }
9
+
10
+ .table {
11
+ width: 100%;
12
+ border-collapse: collapse;
13
+ border-spacing: 0;
14
+ th,
15
+ td {
16
+ padding-inline: var(--spacing-padding-px-4);
17
+ }
18
+ }
19
+ .table__header {
20
+ th {
21
+ @apply h-11 text-left;
22
+ background-color: var(--color-elevation-level-2);
23
+ }
24
+ }
25
+ .table__body {
26
+ tr {
27
+ @apply transition-colors duration-200;
28
+ border-top: solid 1px var(--color-surface-300);
29
+ &:hover:not(.table__no-hover) {
30
+ background-color: var(--color-elevation-state-hover-subtle);
31
+ }
32
+ &:first-child {
33
+ border-top: none;
34
+ }
35
+ &.table__row-yellow {
36
+ background-color: var(--color-yellow-50);
37
+ border: 1px solid transparent;
38
+ position: relative;
39
+ &::after {
40
+ content: '';
41
+ position: absolute;
42
+ inset: -1px;
43
+ pointer-events: none;
44
+ background-image:
45
+ repeating-linear-gradient(
46
+ to right,
47
+ var(--color-yellow-600) 0,
48
+ var(--color-yellow-600) 8px,
49
+ transparent 8px,
50
+ transparent 16px
51
+ ),
52
+ repeating-linear-gradient(
53
+ to right,
54
+ var(--color-yellow-600) 0,
55
+ var(--color-yellow-600) 8px,
56
+ transparent 8px,
57
+ transparent 16px
58
+ ),
59
+ repeating-linear-gradient(
60
+ to bottom,
61
+ var(--color-yellow-600) 0,
62
+ var(--color-yellow-600) 8px,
63
+ transparent 8px,
64
+ transparent 16px
65
+ ),
66
+ repeating-linear-gradient(
67
+ to bottom,
68
+ var(--color-yellow-600) 0,
69
+ var(--color-yellow-600) 8px,
70
+ transparent 8px,
71
+ transparent 16px
72
+ );
73
+ background-size:
74
+ 100% 1px,
75
+ 100% 1px,
76
+ 1px 100%,
77
+ 1px 100%;
78
+ background-position: top, bottom, left, right;
79
+ background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
80
+ }
81
+ &:hover {
82
+ background-color: var(--color-yellow-100);
83
+ }
84
+ & + tr {
85
+ border-top: none;
86
+ }
87
+ }
88
+ &.table__row-border-0 {
89
+ border-top: none;
90
+ &:not(:nth-of-type(1)) {
91
+ td {
92
+ vertical-align: top;
93
+ padding-top: 0;
94
+ }
95
+ }
96
+ }
97
+ }
98
+ td {
99
+ padding-block: var(--spacing-padding-px-4);
100
+ &.table__cell-nested {
101
+ padding: 0;
102
+ overflow: hidden;
103
+ tr:last-child {
104
+ border-bottom: none;
105
+ }
106
+ }
107
+ }
108
+ .table__nested-wrapper {
109
+ overflow: hidden;
110
+ display: block;
111
+ }
112
+ .button__icon {
113
+ @apply transition-transform duration-200;
114
+ }
115
+ }
116
+
117
+ .table__row-nested {
118
+ border-left: solid 4px var(--color-primary-brand);
119
+ }
120
+
121
+ .table__button-expanded {
122
+ .button__icon {
123
+ @apply rotate-180;
124
+ }
125
+ }
126
+
127
+ .table__row-clickable {
128
+ cursor: pointer;
129
+ }
130
+
131
+ .table__button {
132
+ width: 136px;
133
+ }
134
+
135
+ .table__row-grouped {
136
+ > td {
137
+ padding: 0;
138
+ }
139
+ }
140
+
141
+ .table__total-container {
142
+ max-width: 1680px;
143
+ }
144
+
145
+ .table__total {
146
+ tr {
147
+ border: 1px solid transparent;
148
+ position: relative;
149
+ &::after {
150
+ content: '';
151
+ position: absolute;
152
+ inset: -1px;
153
+ pointer-events: none;
154
+ background-image:
155
+ repeating-linear-gradient(
156
+ to right,
157
+ var(--divider-color-default) 0,
158
+ var(--divider-color-default) 12px,
159
+ transparent 12px,
160
+ transparent 24px
161
+ ),
162
+ repeating-linear-gradient(
163
+ to right,
164
+ var(--divider-color-default) 0,
165
+ var(--divider-color-default) 12px,
166
+ transparent 12px,
167
+ transparent 24px
168
+ );
169
+ background-size:
170
+ 100% 1px,
171
+ 100% 1px;
172
+ background-position: top, bottom;
173
+ background-repeat: repeat-x, repeat-x;
174
+ }
175
+ }
176
+ td {
177
+ padding-block: var(--spacing-padding-px-4);
178
+ &:last-child {
179
+ width: 160px;
180
+ @media (min-width: 1680px) {
181
+ width: var(--last-column-width);
182
+ }
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,273 @@
1
+ import { cn } from '@/src/lib/utils';
2
+ import { AnimatePresence, domAnimation, LazyMotion } from 'motion/react';
3
+ import * as motion from 'motion/react-m';
4
+ import { Fragment, useEffect, useRef, useState } from 'react';
5
+ import { Text } from '../../atoms/Typography/Typography';
6
+ import Pagination, { PaginationProps } from '../../molecules/Pagination/Pagination';
7
+ import './Table.css';
8
+ import { ColumnType, TableCell } from './TableCell';
9
+
10
+ export type TableRowData<T = any> = {
11
+ /** Unique identifier for the row */
12
+ id?: string;
13
+ /** Whether the row is visible */
14
+ visible?: boolean;
15
+ /**
16
+ * Class name for the row
17
+ *
18
+ * Available classes:
19
+ * - table__row-yellow: For yellow rows
20
+ * - table__row-border-0: For no border
21
+ */
22
+ className?: string;
23
+
24
+ /** Children rows for the row */
25
+ children?: T[];
26
+ };
27
+
28
+ export interface TableProps<T extends TableRowData<T>> {
29
+ /** Columns definitions for the table */
30
+ columns: ColumnType<T>[];
31
+
32
+ /** Data for the table */
33
+ data: T[];
34
+
35
+ /** Callback function to be called when a row is clicked */
36
+ onClickRow?: (e: React.MouseEvent<HTMLTableRowElement>, row: T) => void;
37
+
38
+ /** Pagination configuration for the table */
39
+ pagination?: PaginationProps;
40
+
41
+ /** Total rows in the table */
42
+ totalRows?: Record<string, string | number>;
43
+
44
+ /** Whether the child rows are visible */
45
+ isGrouped?: boolean;
46
+ }
47
+
48
+ /**
49
+ * A component for displaying nested content in a table row.
50
+ *
51
+ * @example
52
+ * <NestedContent
53
+ * rowIndex={rowIndex}
54
+ * columns={columns}
55
+ * children={children}
56
+ * onClickRow={onClickRow}
57
+ * />
58
+ * @param NestedContentProps<T>
59
+ * @returns
60
+ */
61
+ const NestedContent = <T extends TableRowData<T>>({
62
+ rowIndex,
63
+ columns,
64
+ children,
65
+ isGrouped,
66
+ onClickRow,
67
+ }: {
68
+ rowIndex: number;
69
+ columns: ColumnType<T>[];
70
+ children: T[];
71
+ isGrouped?: boolean;
72
+ onClickRow?: (e: React.MouseEvent<HTMLTableRowElement>, row: T) => void;
73
+ }) => {
74
+ const contentRef = useRef<HTMLDivElement>(null);
75
+ const [height, setHeight] = useState<number | 'auto'>(0);
76
+
77
+ useEffect(() => {
78
+ if (contentRef.current) {
79
+ const measuredHeight = contentRef.current.scrollHeight;
80
+ setHeight(measuredHeight);
81
+ }
82
+ }, [children]);
83
+
84
+ const Tag = isGrouped ? 'div' : motion.div;
85
+
86
+ return (
87
+ <Tag
88
+ ref={contentRef}
89
+ initial={{ height: 0, opacity: 0 }}
90
+ animate={{ height, opacity: 1 }}
91
+ exit={{ height: 0, opacity: 0 }}
92
+ transition={{
93
+ height: { duration: 0.2, ease: 'easeInOut' },
94
+ opacity: { duration: 0.15, ease: 'easeInOut' },
95
+ }}
96
+ className="table__nested-wrapper">
97
+ <table className="table">
98
+ <tbody>
99
+ {children.map((child, childIndex) => (
100
+ <tr
101
+ key={`ch-${rowIndex}-${childIndex}`}
102
+ className={cn(child.className, {
103
+ 'table__row-clickable': onClickRow,
104
+ })}
105
+ onClick={(e) => onClickRow?.(e, child as T)}>
106
+ <TableCell<T> columns={columns} row={child as T} rowIndex={childIndex} />
107
+ </tr>
108
+ ))}
109
+ </tbody>
110
+ </table>
111
+ </Tag>
112
+ );
113
+ };
114
+
115
+ /**
116
+ * A table component for displaying structured data in rows and columns. Supports customizable column definitions and data rows.
117
+ *
118
+ * @example
119
+ * <Table
120
+ * columns={columns}
121
+ * data={data}
122
+ * pagination={pagination}
123
+ * onClickRow={onClickRow}
124
+ * />
125
+ *
126
+ * @param props TableProps<T>
127
+ * @returns React.ReactNode
128
+ *
129
+ */
130
+ export const Table = <T extends TableRowData<T>>(props: TableProps<T>) => {
131
+ const { columns, data, pagination, isGrouped, totalRows = {}, onClickRow } = props;
132
+
133
+ const normalizeLastColumnWidth = () => {
134
+ const width = columns[columns.length - 1].width;
135
+ if (typeof width === 'number') {
136
+ return `${width - 10}px`;
137
+ }
138
+ return width;
139
+ };
140
+
141
+ const hasTotal = Object.keys(totalRows).length > 0;
142
+
143
+ return (
144
+ <LazyMotion features={domAnimation}>
145
+ <div>
146
+ <div
147
+ className={cn('table-container', { 'table-container--no-total': !hasTotal })}>
148
+ <table className="table">
149
+ <thead className="table__header">
150
+ <tr>
151
+ {columns.map((column, columnIndex) => (
152
+ <th
153
+ key={`hd-${columnIndex}`}
154
+ className={column.className}
155
+ style={
156
+ column.width
157
+ ? { minWidth: column.width, width: column.width }
158
+ : undefined
159
+ }>
160
+ <Text variant="bold" size="sm">
161
+ {column.header}
162
+ </Text>
163
+ </th>
164
+ ))}
165
+ </tr>
166
+ </thead>
167
+ <tbody className="table__body">
168
+ {data.map((row, rowIndex) => {
169
+ const hasVisibleChildren = row.children?.some((child) => child.visible);
170
+
171
+ const defaultTable = (
172
+ <tr
173
+ className={cn(row.className, {
174
+ 'table__row-nested': row.children?.length,
175
+ 'table__row-clickable': onClickRow,
176
+ })}
177
+ onClick={(e) => onClickRow?.(e, row)}>
178
+ <TableCell<T> columns={columns} row={row} rowIndex={rowIndex} />
179
+ </tr>
180
+ );
181
+
182
+ return (
183
+ <Fragment key={`rw-${rowIndex}`}>
184
+ {isGrouped ? (
185
+ row.children && row.children.length > 0 ? (
186
+ <tr className="table__row-grouped">
187
+ <td colSpan={columns.length}>
188
+ <NestedContent<T>
189
+ isGrouped={isGrouped}
190
+ rowIndex={rowIndex}
191
+ columns={columns}
192
+ children={row.children || []}
193
+ onClickRow={onClickRow}
194
+ />
195
+ </td>
196
+ </tr>
197
+ ) : (
198
+ defaultTable
199
+ )
200
+ ) : (
201
+ <>
202
+ {defaultTable}
203
+ <AnimatePresence initial={false}>
204
+ {hasVisibleChildren && (
205
+ <tr
206
+ key={`nested-${rowIndex}`}
207
+ className={cn('table__no-hover', {
208
+ 'table__row-nested':
209
+ row.children && row.children.length > 0,
210
+ })}>
211
+ <td colSpan={columns.length} className="table__cell-nested">
212
+ <NestedContent<T>
213
+ rowIndex={rowIndex}
214
+ columns={columns}
215
+ children={row.children || []}
216
+ onClickRow={onClickRow}
217
+ />
218
+ </td>
219
+ </tr>
220
+ )}
221
+ </AnimatePresence>
222
+ </>
223
+ )}
224
+ </Fragment>
225
+ );
226
+ })}
227
+ </tbody>
228
+ </table>
229
+ </div>
230
+ {hasTotal && (
231
+ <div className="table__total-container">
232
+ <table className="table">
233
+ <tbody className="table__total">
234
+ <tr>
235
+ <td colSpan={columns.length - 1}></td>
236
+ <td
237
+ style={
238
+ {
239
+ '--last-column-width': normalizeLastColumnWidth(),
240
+ } as React.CSSProperties
241
+ }>
242
+ <div className="relative">
243
+ <Text
244
+ size="md"
245
+ variant="bold"
246
+ className="absolute top-0 -left-3 -translate-x-full">
247
+ Total :{' '}
248
+ </Text>
249
+ <div>
250
+ {Object.entries(totalRows).map(([currency, total]) => (
251
+ <div key={currency}>
252
+ <Text size="md" variant="bold">
253
+ {currency} {total}
254
+ </Text>
255
+ </div>
256
+ ))}
257
+ </div>
258
+ </div>
259
+ </td>
260
+ </tr>
261
+ </tbody>
262
+ </table>
263
+ </div>
264
+ )}
265
+ {pagination && (
266
+ <div className="flex justify-end mt-4">
267
+ <Pagination {...pagination} />
268
+ </div>
269
+ )}
270
+ </div>
271
+ </LazyMotion>
272
+ );
273
+ };
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { TableRowData } from './Table';
3
+
4
+ export type ColumnType<T = TableRowData> = {
5
+ header: string;
6
+ key: Extract<keyof T, string> | 'actions';
7
+ className?: string;
8
+ width?: number | string;
9
+ cell: (
10
+ value: T[Extract<keyof T, string>],
11
+ rawData: T,
12
+ index?: number
13
+ ) => React.ReactNode;
14
+ };
15
+
16
+ export interface TableCellProps<T = TableRowData> {
17
+ columns: ColumnType<T>[];
18
+ row: T;
19
+ rowIndex: number;
20
+ }
21
+ export const TableCell = <T extends TableRowData>(props: TableCellProps<T>) => {
22
+ const { columns, row, rowIndex } = props;
23
+ return (
24
+ <>
25
+ {columns.map((column, columnIndex) => (
26
+ <td
27
+ key={`cl-${rowIndex}-${columnIndex}`}
28
+ style={
29
+ column.width ? { minWidth: column.width, width: column.width } : undefined
30
+ }>
31
+ {column.key === 'actions' ? (
32
+ <div>{column.cell({} as T[Extract<keyof T, string>], row, rowIndex)}</div>
33
+ ) : (
34
+ column.cell(row[column.key], row, rowIndex)
35
+ )}
36
+ </td>
37
+ ))}
38
+ </>
39
+ );
40
+ };