react-native-mantine 0.15.0 → 0.16.0
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.
- package/README.md +45 -345
- package/lib/commonjs/components/RingProgress/index.js +76 -53
- package/lib/commonjs/components/RingProgress/index.js.map +1 -1
- package/lib/commonjs/components/Table/index.js +257 -273
- package/lib/commonjs/components/Table/index.js.map +1 -1
- package/lib/commonjs/components/index.js +29 -29
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/module/components/RingProgress/index.js +77 -54
- package/lib/module/components/RingProgress/index.js.map +1 -1
- package/lib/module/components/Table/index.js +257 -274
- package/lib/module/components/Table/index.js.map +1 -1
- package/lib/module/components/index.js +3 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/typescript/commonjs/src/components/RingProgress/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/Table/index.d.ts +17 -83
- package/lib/typescript/commonjs/src/components/Table/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/components/index.d.ts +1 -1
- package/lib/typescript/commonjs/src/components/index.d.ts.map +1 -1
- package/lib/typescript/module/src/components/RingProgress/index.d.ts.map +1 -1
- package/lib/typescript/module/src/components/Table/index.d.ts +17 -83
- package/lib/typescript/module/src/components/Table/index.d.ts.map +1 -1
- package/lib/typescript/module/src/components/index.d.ts +1 -1
- package/lib/typescript/module/src/components/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/RingProgress/index.tsx +88 -55
- package/src/components/Table/index.tsx +333 -413
- package/src/components/index.tsx +3 -1
- package/lib/commonjs/components/Table/Table.example.js +0 -323
- package/lib/commonjs/components/Table/Table.example.js.map +0 -1
- package/lib/module/components/Table/Table.example.js +0 -318
- package/lib/module/components/Table/Table.example.js.map +0 -1
- package/lib/typescript/commonjs/src/components/Table/Table.example.d.ts +0 -13
- package/lib/typescript/commonjs/src/components/Table/Table.example.d.ts.map +0 -1
- package/lib/typescript/module/src/components/Table/Table.example.d.ts +0 -13
- package/lib/typescript/module/src/components/Table/Table.example.d.ts.map +0 -1
- package/src/components/Table/Table.example.tsx +0 -215
|
@@ -1,370 +1,271 @@
|
|
|
1
|
-
import React, { forwardRef
|
|
2
|
-
import { ScrollView } from 'react-native';
|
|
3
|
-
import type { LayoutChangeEvent, DimensionValue } from 'react-native';
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { View, ScrollView } from 'react-native';
|
|
4
3
|
import { BoxView } from '../BoxView';
|
|
5
4
|
import { Text } from '../Text';
|
|
6
|
-
import type { DefaultProps,
|
|
5
|
+
import type { DefaultProps, MantineNumberSize } from '../../theme/types';
|
|
7
6
|
import { useComponentDefaultProps } from '../../theme/theme-provider';
|
|
8
7
|
import { createStyles } from '../../theme';
|
|
9
8
|
import { rem } from '../../theme/utils/rem';
|
|
10
|
-
import { withTextWrapper, type WithTextWrapperProps } from '../../theme/utils/withTextWrapper';
|
|
11
|
-
|
|
12
|
-
interface TableContextValue {
|
|
13
|
-
striped: boolean;
|
|
14
|
-
highlightOnHover: boolean;
|
|
15
|
-
withBorder: boolean;
|
|
16
|
-
withColumnBorders: boolean;
|
|
17
|
-
fontSize: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
18
|
-
verticalSpacing: SpacingValue;
|
|
19
|
-
horizontalSpacing: SpacingValue;
|
|
20
|
-
columnWidths: number[];
|
|
21
|
-
onCellLayout: (columnIndex: number, width: number) => void;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const TableContext = createContext<TableContextValue | null>(null);
|
|
25
|
-
|
|
26
|
-
const useTableContext = () => {
|
|
27
|
-
const context = useContext(TableContext);
|
|
28
|
-
return context;
|
|
29
|
-
};
|
|
30
9
|
|
|
31
10
|
export interface TableProps extends DefaultProps {
|
|
32
|
-
/**
|
|
33
|
-
children?: React.ReactNode;
|
|
34
|
-
|
|
35
|
-
/** Horizontal scroll on overflow */
|
|
36
|
-
horizontalSpacing?: SpacingValue;
|
|
37
|
-
|
|
38
|
-
/** Vertical spacing between rows */
|
|
39
|
-
verticalSpacing?: SpacingValue;
|
|
40
|
-
|
|
41
|
-
/** Font size */
|
|
42
|
-
fontSize?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
43
|
-
|
|
44
|
-
/** Add striped rows styling */
|
|
11
|
+
/** If true every odd row of table will have gray background color */
|
|
45
12
|
striped?: boolean;
|
|
46
13
|
|
|
47
|
-
/**
|
|
14
|
+
/** If true row will have hover color */
|
|
48
15
|
highlightOnHover?: boolean;
|
|
49
16
|
|
|
50
|
-
/**
|
|
51
|
-
withBorder?: boolean;
|
|
52
|
-
|
|
53
|
-
/** Add borders between columns */
|
|
54
|
-
withColumnBorders?: boolean;
|
|
55
|
-
|
|
56
|
-
/** Caption position */
|
|
17
|
+
/** Table caption position */
|
|
57
18
|
captionSide?: 'top' | 'bottom';
|
|
58
19
|
|
|
59
|
-
/**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
/** Flex value for the table container (e.g., 1 to fill available space) */
|
|
63
|
-
flex?: number;
|
|
20
|
+
/** Horizontal cells spacing from theme.spacing or any valid value */
|
|
21
|
+
horizontalSpacing?: MantineNumberSize;
|
|
64
22
|
|
|
65
|
-
/**
|
|
66
|
-
|
|
23
|
+
/** Vertical cells spacing from theme.spacing or any valid value */
|
|
24
|
+
verticalSpacing?: MantineNumberSize;
|
|
67
25
|
|
|
68
|
-
/**
|
|
69
|
-
|
|
26
|
+
/** Sets font size of all text inside table */
|
|
27
|
+
fontSize?: MantineNumberSize;
|
|
70
28
|
|
|
71
|
-
/**
|
|
72
|
-
|
|
29
|
+
/** Add border to table */
|
|
30
|
+
withBorder?: boolean;
|
|
73
31
|
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
-
}
|
|
32
|
+
/** Add border to columns */
|
|
33
|
+
withColumnBorders?: boolean;
|
|
77
34
|
|
|
78
|
-
|
|
79
|
-
/** Thead children */
|
|
35
|
+
/** Table children (THead, TBody, TFoot, Caption) */
|
|
80
36
|
children?: React.ReactNode;
|
|
81
37
|
|
|
82
38
|
/** Additional styles */
|
|
83
39
|
style?: any;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface TableTbodyProps extends DefaultProps {
|
|
87
|
-
/** Tbody children */
|
|
88
|
-
children?: React.ReactNode;
|
|
89
40
|
|
|
90
|
-
/**
|
|
91
|
-
|
|
41
|
+
/** Enable horizontal scrolling */
|
|
42
|
+
horizontallyScrollable?: boolean;
|
|
92
43
|
}
|
|
93
44
|
|
|
94
|
-
|
|
95
|
-
/**
|
|
45
|
+
interface TableCellProps extends DefaultProps {
|
|
46
|
+
/** Cell content */
|
|
96
47
|
children?: React.ReactNode;
|
|
97
48
|
|
|
98
49
|
/** Additional styles */
|
|
99
50
|
style?: any;
|
|
51
|
+
|
|
52
|
+
/** Column span */
|
|
53
|
+
colSpan?: number;
|
|
100
54
|
}
|
|
101
55
|
|
|
102
|
-
|
|
103
|
-
/**
|
|
56
|
+
interface TableRowProps extends DefaultProps {
|
|
57
|
+
/** Row content */
|
|
104
58
|
children?: React.ReactNode;
|
|
105
59
|
|
|
106
60
|
/** Additional styles */
|
|
107
61
|
style?: any;
|
|
108
|
-
|
|
109
|
-
/** Internal row index */
|
|
110
|
-
__index?: number;
|
|
111
62
|
}
|
|
112
63
|
|
|
113
|
-
|
|
114
|
-
/**
|
|
64
|
+
interface TableSectionProps extends DefaultProps {
|
|
65
|
+
/** Section content */
|
|
115
66
|
children?: React.ReactNode;
|
|
116
67
|
|
|
117
68
|
/** Additional styles */
|
|
118
69
|
style?: any;
|
|
119
|
-
|
|
120
|
-
/** Internal column index */
|
|
121
|
-
__columnIndex?: number;
|
|
122
70
|
}
|
|
123
71
|
|
|
124
|
-
|
|
125
|
-
/**
|
|
72
|
+
interface TableCaptionProps extends DefaultProps {
|
|
73
|
+
/** Caption content */
|
|
126
74
|
children?: React.ReactNode;
|
|
127
75
|
|
|
128
76
|
/** Additional styles */
|
|
129
77
|
style?: any;
|
|
130
|
-
|
|
131
|
-
/** Internal column index */
|
|
132
|
-
__columnIndex?: number;
|
|
133
78
|
}
|
|
134
79
|
|
|
135
|
-
const
|
|
136
|
-
xs: rem(10),
|
|
137
|
-
sm: rem(12),
|
|
138
|
-
md: rem(14),
|
|
139
|
-
lg: rem(16),
|
|
140
|
-
xl: rem(18),
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const useTableStyles = createStyles(
|
|
144
|
-
(
|
|
145
|
-
theme,
|
|
146
|
-
{
|
|
147
|
-
withBorder,
|
|
148
|
-
captionSide,
|
|
149
|
-
flex,
|
|
150
|
-
flexGrow,
|
|
151
|
-
flexShrink,
|
|
152
|
-
flexBasis,
|
|
153
|
-
}: {
|
|
154
|
-
withBorder: boolean;
|
|
155
|
-
captionSide: 'top' | 'bottom';
|
|
156
|
-
flex?: number;
|
|
157
|
-
flexGrow?: number;
|
|
158
|
-
flexShrink?: number;
|
|
159
|
-
flexBasis?: DimensionValue;
|
|
160
|
-
}
|
|
161
|
-
) => ({
|
|
162
|
-
wrapper: {
|
|
163
|
-
// Apply flex properties to allow table to expand in container
|
|
164
|
-
...(flex !== undefined && { flex }),
|
|
165
|
-
...(flexGrow !== undefined && { flexGrow }),
|
|
166
|
-
...(flexShrink !== undefined && { flexShrink }),
|
|
167
|
-
...(flexBasis !== undefined && { flexBasis }),
|
|
168
|
-
} as any,
|
|
169
|
-
root: {
|
|
170
|
-
width: '100%',
|
|
171
|
-
borderCollapse: 'collapse' as any,
|
|
172
|
-
...(withBorder && {
|
|
173
|
-
borderWidth: 1,
|
|
174
|
-
borderColor:
|
|
175
|
-
theme.colorScheme === 'dark'
|
|
176
|
-
? theme.colors.dark?.[4]
|
|
177
|
-
: theme.colors.gray?.[3],
|
|
178
|
-
}),
|
|
179
|
-
},
|
|
180
|
-
caption: {
|
|
181
|
-
fontSize: theme.fontSizes.sm as number,
|
|
182
|
-
color:
|
|
183
|
-
theme.colorScheme === 'dark'
|
|
184
|
-
? theme.colors.dark?.[2]
|
|
185
|
-
: theme.colors.gray?.[6],
|
|
186
|
-
paddingVertical: theme.spacing.xs,
|
|
187
|
-
textAlign: 'center',
|
|
188
|
-
...(captionSide === 'bottom' && { order: 1 }),
|
|
189
|
-
},
|
|
190
|
-
})
|
|
191
|
-
);
|
|
192
|
-
|
|
193
|
-
const useTableHeadStyles = createStyles((theme) => ({
|
|
194
|
-
thead: {
|
|
195
|
-
borderBottomWidth: 1,
|
|
196
|
-
borderBottomColor:
|
|
197
|
-
theme.colorScheme === 'dark'
|
|
198
|
-
? theme.colors.dark?.[4]
|
|
199
|
-
: theme.colors.gray?.[3],
|
|
200
|
-
},
|
|
201
|
-
}));
|
|
202
|
-
|
|
203
|
-
const useTableRowStyles = createStyles(
|
|
204
|
-
(
|
|
205
|
-
theme,
|
|
206
|
-
{
|
|
207
|
-
striped,
|
|
208
|
-
isEven,
|
|
209
|
-
}: {
|
|
210
|
-
striped: boolean;
|
|
211
|
-
highlightOnHover: boolean;
|
|
212
|
-
isEven: boolean;
|
|
213
|
-
}
|
|
214
|
-
) => ({
|
|
215
|
-
tr: {
|
|
216
|
-
flexDirection: 'row',
|
|
217
|
-
borderBottomWidth: 1,
|
|
218
|
-
borderBottomColor:
|
|
219
|
-
theme.colorScheme === 'dark'
|
|
220
|
-
? theme.colors.dark?.[4]
|
|
221
|
-
: theme.colors.gray?.[3],
|
|
222
|
-
...(striped &&
|
|
223
|
-
isEven && {
|
|
224
|
-
backgroundColor:
|
|
225
|
-
theme.colorScheme === 'dark'
|
|
226
|
-
? theme.colors.dark?.[6]
|
|
227
|
-
: theme.colors.gray?.[0],
|
|
228
|
-
}),
|
|
229
|
-
},
|
|
230
|
-
})
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
const useTableCellStyles = createStyles(
|
|
80
|
+
const useStyles = createStyles(
|
|
234
81
|
(
|
|
235
82
|
theme,
|
|
236
83
|
{
|
|
237
|
-
fontSize,
|
|
238
|
-
verticalSpacing,
|
|
239
84
|
horizontalSpacing,
|
|
85
|
+
verticalSpacing,
|
|
86
|
+
fontSize,
|
|
87
|
+
withBorder,
|
|
240
88
|
withColumnBorders,
|
|
241
|
-
|
|
242
|
-
width,
|
|
89
|
+
striped,
|
|
243
90
|
}: {
|
|
244
|
-
|
|
245
|
-
verticalSpacing:
|
|
246
|
-
|
|
91
|
+
horizontalSpacing: MantineNumberSize;
|
|
92
|
+
verticalSpacing: MantineNumberSize;
|
|
93
|
+
fontSize: MantineNumberSize;
|
|
94
|
+
withBorder: boolean;
|
|
247
95
|
withColumnBorders: boolean;
|
|
248
|
-
|
|
249
|
-
width?: number;
|
|
96
|
+
striped: boolean;
|
|
250
97
|
}
|
|
251
98
|
) => {
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
99
|
+
const borderColor =
|
|
100
|
+
theme.colorScheme === 'dark'
|
|
101
|
+
? (theme.colors.dark || [])[4]
|
|
102
|
+
: (theme.colors.gray || [])[3];
|
|
103
|
+
|
|
104
|
+
const getSpacing = (size: MantineNumberSize) => {
|
|
105
|
+
if (typeof size === 'number') return rem(size);
|
|
106
|
+
return theme.spacing[size] || theme.spacing.xs;
|
|
255
107
|
};
|
|
256
108
|
|
|
257
|
-
const
|
|
258
|
-
if (typeof
|
|
259
|
-
return theme.
|
|
109
|
+
const getFontSize = (size: MantineNumberSize) => {
|
|
110
|
+
if (typeof size === 'number') return size;
|
|
111
|
+
return theme.fontSizes[size] || theme.fontSizes.sm;
|
|
260
112
|
};
|
|
261
113
|
|
|
114
|
+
const hPadding = getSpacing(horizontalSpacing);
|
|
115
|
+
const vPadding = getSpacing(verticalSpacing);
|
|
116
|
+
const cellFontSize = getFontSize(fontSize);
|
|
117
|
+
|
|
262
118
|
return {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
119
|
+
root: {
|
|
120
|
+
width: '100%',
|
|
121
|
+
backgroundColor: 'transparent',
|
|
122
|
+
},
|
|
123
|
+
scrollView: {
|
|
124
|
+
width: '100%',
|
|
125
|
+
},
|
|
126
|
+
container: {
|
|
127
|
+
flexDirection: 'column' as const,
|
|
128
|
+
borderWidth: withBorder ? 1 : 0,
|
|
129
|
+
borderColor: withBorder ? borderColor : 'transparent',
|
|
130
|
+
borderStyle: 'solid' as const,
|
|
131
|
+
},
|
|
132
|
+
caption: {
|
|
133
|
+
paddingHorizontal: hPadding,
|
|
134
|
+
paddingVertical: theme.spacing.xs,
|
|
135
|
+
fontSize: theme.fontSizes.sm,
|
|
136
|
+
color:
|
|
137
|
+
theme.colorScheme === 'dark'
|
|
138
|
+
? (theme.colors.dark || [])[2]
|
|
139
|
+
: (theme.colors.gray || [])[6],
|
|
140
|
+
textAlign: 'left' as const,
|
|
141
|
+
},
|
|
142
|
+
captionTop: {
|
|
143
|
+
marginBottom: 0,
|
|
144
|
+
},
|
|
145
|
+
captionBottom: {
|
|
146
|
+
marginTop: 0,
|
|
147
|
+
},
|
|
148
|
+
thead: {
|
|
149
|
+
flexDirection: 'column' as const,
|
|
150
|
+
},
|
|
151
|
+
tbody: {
|
|
152
|
+
flexDirection: 'column' as const,
|
|
153
|
+
},
|
|
154
|
+
tfoot: {
|
|
155
|
+
flexDirection: 'column' as const,
|
|
156
|
+
},
|
|
157
|
+
tr: {
|
|
158
|
+
flexDirection: 'row' as const,
|
|
282
159
|
},
|
|
160
|
+
th: {
|
|
161
|
+
flex: 1,
|
|
162
|
+
paddingHorizontal: hPadding,
|
|
163
|
+
paddingVertical: vPadding,
|
|
164
|
+
borderBottomWidth: 1,
|
|
165
|
+
borderBottomColor: borderColor,
|
|
166
|
+
borderBottomStyle: 'solid' as const,
|
|
167
|
+
borderRightWidth: withColumnBorders ? 1 : 0,
|
|
168
|
+
borderRightColor: withColumnBorders ? borderColor : 'transparent',
|
|
169
|
+
borderRightStyle: 'solid' as const,
|
|
170
|
+
justifyContent: 'center' as const,
|
|
171
|
+
},
|
|
172
|
+
thText: {
|
|
173
|
+
fontWeight: 'bold' as const,
|
|
174
|
+
color:
|
|
175
|
+
theme.colorScheme === 'dark'
|
|
176
|
+
? (theme.colors.dark || [])[0]
|
|
177
|
+
: (theme.colors.gray || [])[7],
|
|
178
|
+
fontSize: cellFontSize,
|
|
179
|
+
},
|
|
180
|
+
td: {
|
|
181
|
+
flex: 1,
|
|
182
|
+
paddingHorizontal: hPadding,
|
|
183
|
+
paddingVertical: vPadding,
|
|
184
|
+
borderTopWidth: 1,
|
|
185
|
+
borderTopColor: borderColor,
|
|
186
|
+
borderTopStyle: 'solid' as const,
|
|
187
|
+
borderRightWidth: withColumnBorders ? 1 : 0,
|
|
188
|
+
borderRightColor: withColumnBorders ? borderColor : 'transparent',
|
|
189
|
+
borderRightStyle: 'solid' as const,
|
|
190
|
+
justifyContent: 'center' as const,
|
|
191
|
+
},
|
|
192
|
+
tdText: {
|
|
193
|
+
color:
|
|
194
|
+
theme.colorScheme === 'dark'
|
|
195
|
+
? (theme.colors.dark || [])[0]
|
|
196
|
+
: theme.black,
|
|
197
|
+
fontSize: cellFontSize,
|
|
198
|
+
},
|
|
199
|
+
firstBodyRow: {
|
|
200
|
+
borderTopWidth: 0,
|
|
201
|
+
},
|
|
202
|
+
lastCell: {
|
|
203
|
+
borderRightWidth: 0,
|
|
204
|
+
},
|
|
205
|
+
stripedRow: striped
|
|
206
|
+
? {
|
|
207
|
+
backgroundColor:
|
|
208
|
+
theme.colorScheme === 'dark'
|
|
209
|
+
? (theme.colors.dark || [])[6]
|
|
210
|
+
: (theme.colors.gray || [])[0],
|
|
211
|
+
}
|
|
212
|
+
: {},
|
|
283
213
|
};
|
|
284
214
|
}
|
|
285
215
|
);
|
|
286
216
|
|
|
287
217
|
const defaultProps: Partial<TableProps> = {
|
|
288
|
-
horizontalSpacing: 'xs',
|
|
289
|
-
verticalSpacing: 'xs',
|
|
290
|
-
fontSize: 'sm',
|
|
291
218
|
striped: false,
|
|
292
219
|
highlightOnHover: false,
|
|
220
|
+
captionSide: 'top',
|
|
221
|
+
horizontalSpacing: 'xs',
|
|
222
|
+
fontSize: 'sm',
|
|
223
|
+
verticalSpacing: 7,
|
|
293
224
|
withBorder: false,
|
|
294
225
|
withColumnBorders: false,
|
|
295
|
-
|
|
226
|
+
horizontallyScrollable: false,
|
|
296
227
|
};
|
|
297
228
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
highlightOnHover: _highlightOnHover,
|
|
306
|
-
withBorder,
|
|
307
|
-
withColumnBorders,
|
|
308
|
-
captionSide,
|
|
309
|
-
caption,
|
|
310
|
-
flex,
|
|
311
|
-
flexGrow,
|
|
312
|
-
flexShrink,
|
|
313
|
-
flexBasis,
|
|
314
|
-
style,
|
|
315
|
-
...others
|
|
316
|
-
} = useComponentDefaultProps('Table', defaultProps, props);
|
|
229
|
+
// Context to share table configuration with child components
|
|
230
|
+
interface TableContextValue {
|
|
231
|
+
styles: any;
|
|
232
|
+
sx: any;
|
|
233
|
+
striped: boolean;
|
|
234
|
+
highlightOnHover: boolean;
|
|
235
|
+
}
|
|
317
236
|
|
|
318
|
-
|
|
319
|
-
{ withBorder, captionSide, flex, flexGrow, flexShrink, flexBasis },
|
|
320
|
-
{ name: 'Table' }
|
|
321
|
-
) as any;
|
|
237
|
+
const TableContext = React.createContext<TableContextValue | null>(null);
|
|
322
238
|
|
|
323
|
-
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}, []);
|
|
239
|
+
const useTableContext = () => {
|
|
240
|
+
const context = React.useContext(TableContext);
|
|
241
|
+
if (!context) {
|
|
242
|
+
throw new Error('Table compound components must be used within Table');
|
|
243
|
+
}
|
|
244
|
+
return context;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// Table Caption Component
|
|
248
|
+
const TableCaption = forwardRef<View, TableCaptionProps>((props, ref) => {
|
|
249
|
+
const { children, style, ...others } = props;
|
|
250
|
+
const { styles, sx } = useTableContext();
|
|
336
251
|
|
|
337
252
|
return (
|
|
338
|
-
<
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
verticalSpacing: verticalSpacing!,
|
|
346
|
-
horizontalSpacing: horizontalSpacing!,
|
|
347
|
-
columnWidths,
|
|
348
|
-
onCellLayout,
|
|
349
|
-
}}
|
|
350
|
-
>
|
|
351
|
-
<ScrollView
|
|
352
|
-
horizontal
|
|
353
|
-
style={styles.wrapper}
|
|
354
|
-
showsHorizontalScrollIndicator
|
|
355
|
-
>
|
|
356
|
-
<BoxView ref={ref} style={sx(styles.root, style)} {...others}>
|
|
357
|
-
{caption && <Text style={styles.caption}>{caption}</Text>}
|
|
358
|
-
{children}
|
|
359
|
-
</BoxView>
|
|
360
|
-
</ScrollView>
|
|
361
|
-
</TableContext.Provider>
|
|
253
|
+
<BoxView ref={ref} style={sx(styles.caption, style)} {...others}>
|
|
254
|
+
{typeof children === 'string' ? (
|
|
255
|
+
<Text style={styles.caption}>{children}</Text>
|
|
256
|
+
) : (
|
|
257
|
+
children
|
|
258
|
+
)}
|
|
259
|
+
</BoxView>
|
|
362
260
|
);
|
|
363
261
|
});
|
|
364
262
|
|
|
365
|
-
|
|
263
|
+
TableCaption.displayName = 'Table.Caption';
|
|
264
|
+
|
|
265
|
+
// Table Head Component
|
|
266
|
+
const THead = forwardRef<View, TableSectionProps>((props, ref) => {
|
|
366
267
|
const { children, style, ...others } = props;
|
|
367
|
-
const { styles, sx } =
|
|
268
|
+
const { styles, sx } = useTableContext();
|
|
368
269
|
|
|
369
270
|
return (
|
|
370
271
|
<BoxView ref={ref} style={sx(styles.thead, style)} {...others}>
|
|
@@ -373,177 +274,196 @@ const Thead = forwardRef<any, TableTheadProps>((props, ref) => {
|
|
|
373
274
|
);
|
|
374
275
|
});
|
|
375
276
|
|
|
376
|
-
|
|
277
|
+
THead.displayName = 'Table.THead';
|
|
278
|
+
|
|
279
|
+
// Table Body Component
|
|
280
|
+
const TBody = forwardRef<View, TableSectionProps>((props, ref) => {
|
|
377
281
|
const { children, style, ...others } = props;
|
|
282
|
+
const { styles, sx, striped } = useTableContext();
|
|
378
283
|
|
|
379
|
-
|
|
284
|
+
// Process children to add row styling
|
|
285
|
+
const processedChildren = React.Children.map(children, (child, index) => {
|
|
286
|
+
if (!React.isValidElement(child)) return child;
|
|
287
|
+
|
|
288
|
+
const isOddRow = index % 2 === 1;
|
|
289
|
+
const childProps = child.props as any;
|
|
290
|
+
const rowStyle = [
|
|
291
|
+
childProps.style,
|
|
292
|
+
striped && isOddRow && styles.stripedRow,
|
|
293
|
+
].filter(Boolean);
|
|
294
|
+
|
|
295
|
+
return React.cloneElement(child as React.ReactElement<any>, {
|
|
296
|
+
'style': rowStyle.length > 0 ? rowStyle : childProps.style,
|
|
297
|
+
'data-index': index,
|
|
298
|
+
'data-first': index === 0,
|
|
299
|
+
});
|
|
300
|
+
});
|
|
380
301
|
|
|
381
302
|
return (
|
|
382
|
-
<BoxView ref={ref} style={style} {...others}>
|
|
383
|
-
{
|
|
384
|
-
if (!React.isValidElement(child)) return child;
|
|
385
|
-
return React.cloneElement<TableTrProps>(
|
|
386
|
-
child as React.ReactElement<TableTrProps>,
|
|
387
|
-
{
|
|
388
|
-
key: index,
|
|
389
|
-
__index: index,
|
|
390
|
-
}
|
|
391
|
-
);
|
|
392
|
-
})}
|
|
303
|
+
<BoxView ref={ref} style={sx(styles.tbody, style)} {...others}>
|
|
304
|
+
{processedChildren}
|
|
393
305
|
</BoxView>
|
|
394
306
|
);
|
|
395
307
|
});
|
|
396
308
|
|
|
397
|
-
|
|
309
|
+
TBody.displayName = 'Table.TBody';
|
|
310
|
+
|
|
311
|
+
// Table Footer Component
|
|
312
|
+
const TFoot = forwardRef<View, TableSectionProps>((props, ref) => {
|
|
398
313
|
const { children, style, ...others } = props;
|
|
314
|
+
const { styles, sx } = useTableContext();
|
|
399
315
|
|
|
400
316
|
return (
|
|
401
|
-
<BoxView ref={ref} style={style} {...others}>
|
|
317
|
+
<BoxView ref={ref} style={sx(styles.tfoot, style)} {...others}>
|
|
402
318
|
{children}
|
|
403
319
|
</BoxView>
|
|
404
320
|
);
|
|
405
321
|
});
|
|
406
322
|
|
|
407
|
-
|
|
408
|
-
const { children, style, __index, ...others } = props;
|
|
409
|
-
const context = useTableContext();
|
|
323
|
+
TFoot.displayName = 'Table.TFoot';
|
|
410
324
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
isEven: (__index ?? 0) % 2 === 0,
|
|
416
|
-
},
|
|
417
|
-
{ name: 'Tr' }
|
|
418
|
-
) as any;
|
|
419
|
-
|
|
420
|
-
// Add column indices to children (Th and Td components)
|
|
421
|
-
const childrenArray = React.Children.toArray(children);
|
|
422
|
-
const childrenWithColumnIndex = childrenArray.map((child, index) => {
|
|
423
|
-
if (!React.isValidElement(child)) return child;
|
|
424
|
-
return React.cloneElement<TableThProps | TableTdProps>(
|
|
425
|
-
child as React.ReactElement<TableThProps | TableTdProps>,
|
|
426
|
-
{
|
|
427
|
-
__columnIndex: index,
|
|
428
|
-
}
|
|
429
|
-
);
|
|
430
|
-
});
|
|
325
|
+
// Table Row Component
|
|
326
|
+
const Tr = forwardRef<View, TableRowProps>((props, ref) => {
|
|
327
|
+
const { children, style, ...others } = props;
|
|
328
|
+
const { styles, sx } = useTableContext();
|
|
431
329
|
|
|
432
330
|
return (
|
|
433
331
|
<BoxView ref={ref} style={sx(styles.tr, style)} {...others}>
|
|
434
|
-
{
|
|
332
|
+
{children}
|
|
435
333
|
</BoxView>
|
|
436
334
|
);
|
|
437
335
|
});
|
|
438
336
|
|
|
439
|
-
|
|
440
|
-
const { children, style, withTextWrapper: shouldWrapInText = true, __columnIndex, ...others } = props;
|
|
441
|
-
const context = useTableContext();
|
|
442
|
-
|
|
443
|
-
const columnIndex = __columnIndex ?? 0;
|
|
444
|
-
const columnWidth = context?.columnWidths?.[columnIndex];
|
|
337
|
+
Tr.displayName = 'Table.Tr';
|
|
445
338
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
horizontalSpacing: context?.horizontalSpacing ?? 'xs',
|
|
451
|
-
withColumnBorders: context?.withColumnBorders ?? false,
|
|
452
|
-
isHeader: true,
|
|
453
|
-
width: columnWidth,
|
|
454
|
-
},
|
|
455
|
-
{ name: 'Th' }
|
|
456
|
-
) as any;
|
|
339
|
+
// Table Header Cell Component
|
|
340
|
+
const Th = forwardRef<View, TableCellProps>((props, ref) => {
|
|
341
|
+
const { children, style, colSpan, ...others } = props;
|
|
342
|
+
const { styles, sx } = useTableContext();
|
|
457
343
|
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
const { width } = event.nativeEvent.layout;
|
|
461
|
-
if (context?.onCellLayout && width > 0) {
|
|
462
|
-
context.onCellLayout(columnIndex, width);
|
|
463
|
-
}
|
|
464
|
-
},
|
|
465
|
-
[context, columnIndex]
|
|
344
|
+
const cellStyle = [styles.th, colSpan && { flex: colSpan }, style].filter(
|
|
345
|
+
Boolean
|
|
466
346
|
);
|
|
467
347
|
|
|
468
348
|
return (
|
|
469
|
-
<BoxView
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
{withTextWrapper(children, shouldWrapInText, styles.cell)}
|
|
349
|
+
<BoxView ref={ref} style={sx(...cellStyle)} {...others}>
|
|
350
|
+
{typeof children === 'string' ? (
|
|
351
|
+
<Text style={styles.thText}>{children}</Text>
|
|
352
|
+
) : (
|
|
353
|
+
children
|
|
354
|
+
)}
|
|
476
355
|
</BoxView>
|
|
477
356
|
);
|
|
478
357
|
});
|
|
479
358
|
|
|
480
|
-
|
|
481
|
-
const { children, style, withTextWrapper: shouldWrapInText = true, __columnIndex, ...others } = props;
|
|
482
|
-
const context = useTableContext();
|
|
483
|
-
|
|
484
|
-
const columnIndex = __columnIndex ?? 0;
|
|
485
|
-
const columnWidth = context?.columnWidths?.[columnIndex];
|
|
359
|
+
Th.displayName = 'Table.Th';
|
|
486
360
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
withColumnBorders: context?.withColumnBorders ?? false,
|
|
493
|
-
isHeader: false,
|
|
494
|
-
width: columnWidth,
|
|
495
|
-
},
|
|
496
|
-
{ name: 'Td' }
|
|
497
|
-
) as any;
|
|
361
|
+
// Table Data Cell Component
|
|
362
|
+
const Td = forwardRef<View, TableCellProps>((props, ref) => {
|
|
363
|
+
const { children, style, colSpan, ...others } = props;
|
|
364
|
+
const { styles, sx } = useTableContext();
|
|
365
|
+
const isFirstRow = (others as any)['data-first'];
|
|
498
366
|
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
},
|
|
506
|
-
[context, columnIndex]
|
|
507
|
-
);
|
|
367
|
+
const cellStyle = [
|
|
368
|
+
styles.td,
|
|
369
|
+
isFirstRow && styles.firstBodyRow,
|
|
370
|
+
colSpan && { flex: colSpan },
|
|
371
|
+
style,
|
|
372
|
+
].filter(Boolean);
|
|
508
373
|
|
|
509
374
|
return (
|
|
510
|
-
<BoxView
|
|
511
|
-
|
|
512
|
-
style={sx(styles.cell, style)}
|
|
513
|
-
onLayout={handleLayout}
|
|
514
|
-
{...others}
|
|
515
|
-
>
|
|
516
|
-
{withTextWrapper(children, shouldWrapInText, styles.cell)}
|
|
375
|
+
<BoxView ref={ref} style={sx(...cellStyle)} {...others}>
|
|
376
|
+
<Text style={styles.tdText}>{children}</Text>
|
|
517
377
|
</BoxView>
|
|
518
378
|
);
|
|
519
379
|
});
|
|
520
380
|
|
|
521
|
-
Table.displayName = 'Table';
|
|
522
|
-
Thead.displayName = 'Table.Thead';
|
|
523
|
-
Tbody.displayName = 'Table.Tbody';
|
|
524
|
-
Tfoot.displayName = 'Table.Tfoot';
|
|
525
|
-
Tr.displayName = 'Table.Tr';
|
|
526
|
-
Th.displayName = 'Table.Th';
|
|
527
381
|
Td.displayName = 'Table.Td';
|
|
528
382
|
|
|
529
|
-
//
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
383
|
+
// Main Table Component
|
|
384
|
+
export const _Table = forwardRef<View, TableProps>((props, ref) => {
|
|
385
|
+
const {
|
|
386
|
+
striped,
|
|
387
|
+
highlightOnHover,
|
|
388
|
+
captionSide,
|
|
389
|
+
horizontalSpacing,
|
|
390
|
+
verticalSpacing,
|
|
391
|
+
fontSize,
|
|
392
|
+
withBorder,
|
|
393
|
+
withColumnBorders,
|
|
394
|
+
children,
|
|
395
|
+
style,
|
|
396
|
+
horizontallyScrollable,
|
|
397
|
+
...others
|
|
398
|
+
} = useComponentDefaultProps('Table', defaultProps, props);
|
|
540
399
|
|
|
541
|
-
const
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
400
|
+
const { styles, sx } = useStyles(
|
|
401
|
+
{
|
|
402
|
+
horizontalSpacing,
|
|
403
|
+
verticalSpacing,
|
|
404
|
+
fontSize,
|
|
405
|
+
withBorder,
|
|
406
|
+
withColumnBorders,
|
|
407
|
+
striped,
|
|
408
|
+
},
|
|
409
|
+
{ name: 'Table' }
|
|
410
|
+
) as any;
|
|
548
411
|
|
|
549
|
-
|
|
412
|
+
const contextValue: TableContextValue = {
|
|
413
|
+
styles,
|
|
414
|
+
sx,
|
|
415
|
+
striped: striped || false,
|
|
416
|
+
highlightOnHover: highlightOnHover || false,
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const tableContent = (
|
|
420
|
+
<BoxView ref={ref} style={sx(styles.container, style)} {...others}>
|
|
421
|
+
{captionSide === 'top' &&
|
|
422
|
+
React.Children.toArray(children).find(
|
|
423
|
+
(child) =>
|
|
424
|
+
React.isValidElement(child) &&
|
|
425
|
+
(child.type as any).displayName === 'Table.Caption'
|
|
426
|
+
)}
|
|
427
|
+
{React.Children.toArray(children).filter(
|
|
428
|
+
(child) =>
|
|
429
|
+
React.isValidElement(child) &&
|
|
430
|
+
(child.type as any).displayName !== 'Table.Caption'
|
|
431
|
+
)}
|
|
432
|
+
{captionSide === 'bottom' &&
|
|
433
|
+
React.Children.toArray(children).find(
|
|
434
|
+
(child) =>
|
|
435
|
+
React.isValidElement(child) &&
|
|
436
|
+
(child.type as any).displayName === 'Table.Caption'
|
|
437
|
+
)}
|
|
438
|
+
</BoxView>
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
return (
|
|
442
|
+
<TableContext.Provider value={contextValue}>
|
|
443
|
+
{horizontallyScrollable ? (
|
|
444
|
+
<ScrollView
|
|
445
|
+
horizontal
|
|
446
|
+
style={styles.scrollView}
|
|
447
|
+
showsHorizontalScrollIndicator={true}
|
|
448
|
+
>
|
|
449
|
+
{tableContent}
|
|
450
|
+
</ScrollView>
|
|
451
|
+
) : (
|
|
452
|
+
tableContent
|
|
453
|
+
)}
|
|
454
|
+
</TableContext.Provider>
|
|
455
|
+
);
|
|
456
|
+
}) as any;
|
|
457
|
+
|
|
458
|
+
_Table.displayName = 'Table';
|
|
459
|
+
|
|
460
|
+
// Attach compound components
|
|
461
|
+
export const Table = Object.assign(_Table, {
|
|
462
|
+
Caption: TableCaption,
|
|
463
|
+
THead,
|
|
464
|
+
TBody,
|
|
465
|
+
TFoot,
|
|
466
|
+
Tr,
|
|
467
|
+
Th,
|
|
468
|
+
Td,
|
|
469
|
+
});
|