廓形仪rn版本-技术调研
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
5.0 KiB

  1. import React, { createContext, useMemo, useContext } from 'react';
  2. import {
  3. Table as ExpoTable,
  4. THead as ExpoTHead,
  5. TBody as ExpoTBody,
  6. TFoot as ExpoTFoot,
  7. TR as ExpoTR,
  8. Caption as ExpoTCaption,
  9. } from '@expo/html-elements';
  10. import {
  11. tableStyle,
  12. tableHeaderStyle,
  13. tableBodyStyle,
  14. tableFooterStyle,
  15. tableHeadStyle,
  16. tableRowStyleStyle,
  17. tableDataStyle,
  18. tableCaptionStyle,
  19. } from './styles';
  20. import { Text, View } from 'react-native';
  21. const TableHeaderContext = createContext<{
  22. isHeaderRow: boolean;
  23. }>({
  24. isHeaderRow: false,
  25. });
  26. const TableFooterContext = createContext<{
  27. isFooterRow: boolean;
  28. }>({
  29. isFooterRow: false,
  30. });
  31. type ITableProps = React.ComponentProps<typeof ExpoTable>;
  32. type ITableHeaderProps = React.ComponentProps<typeof ExpoTHead>;
  33. type ITableBodyProps = React.ComponentProps<typeof ExpoTBody>;
  34. type ITableFooterProps = React.ComponentProps<typeof ExpoTFoot>;
  35. type ITableHeadProps = React.ComponentProps<typeof View | typeof Text> & {
  36. useRNView?: boolean;
  37. };
  38. type ITableRowProps = React.ComponentProps<typeof ExpoTR>;
  39. type ITableDataProps = React.ComponentProps<typeof View | typeof Text> & {
  40. useRNView?: boolean;
  41. };
  42. type ITableCaptionProps = React.ComponentProps<typeof ExpoTCaption>;
  43. const Table = React.forwardRef<
  44. React.ComponentRef<typeof ExpoTable>,
  45. ITableProps
  46. >(({ className, ...props }, ref) => {
  47. return (
  48. <ExpoTable
  49. // @ts-expect-error : ref type changed
  50. ref={ref}
  51. className={tableStyle({ class: className })}
  52. {...props}
  53. />
  54. );
  55. });
  56. const TableHeader = React.forwardRef<
  57. React.ComponentRef<typeof ExpoTHead>,
  58. ITableHeaderProps
  59. >(function TableHeader({ className, ...props }, ref) {
  60. const contextValue = useMemo(() => {
  61. return {
  62. isHeaderRow: true,
  63. };
  64. }, []);
  65. return (
  66. <TableHeaderContext.Provider value={contextValue}>
  67. <ExpoTHead
  68. // @ts-expect-error : ref type changed
  69. ref={ref}
  70. className={tableHeaderStyle({ class: className })}
  71. {...props}
  72. />
  73. </TableHeaderContext.Provider>
  74. );
  75. });
  76. const TableBody = React.forwardRef<
  77. React.ComponentRef<typeof ExpoTBody>,
  78. ITableBodyProps
  79. >(function TableBody({ className, ...props }, ref) {
  80. return (
  81. <ExpoTBody
  82. // @ts-expect-error : ref type changed
  83. ref={ref}
  84. className={tableBodyStyle({ class: className })}
  85. {...props}
  86. />
  87. );
  88. });
  89. const TableFooter = React.forwardRef<
  90. React.ComponentRef<typeof ExpoTFoot>,
  91. ITableFooterProps
  92. >(function TableFooter({ className, ...props }, ref) {
  93. const contextValue = useMemo(() => {
  94. return {
  95. isFooterRow: true,
  96. };
  97. }, []);
  98. return (
  99. <TableFooterContext.Provider value={contextValue}>
  100. <ExpoTFoot
  101. // @ts-expect-error : ref type changed
  102. ref={ref}
  103. className={tableFooterStyle({ class: className })}
  104. {...props}
  105. />
  106. </TableFooterContext.Provider>
  107. );
  108. });
  109. const TableHead = React.forwardRef<
  110. React.ComponentRef<typeof View | typeof Text>,
  111. ITableHeadProps
  112. >(function TableHead({ useRNView = false, className, ...props }, ref) {
  113. if (useRNView) {
  114. return (
  115. <View
  116. ref={ref}
  117. className={tableHeadStyle({ class: className })}
  118. {...props}
  119. />
  120. );
  121. } else {
  122. return (
  123. <Text
  124. ref={ref}
  125. className={tableHeadStyle({ class: className })}
  126. {...props}
  127. />
  128. );
  129. }
  130. });
  131. const TableRow = React.forwardRef<
  132. React.ComponentRef<typeof ExpoTR>,
  133. ITableRowProps
  134. >(function TableRow({ className, ...props }, ref) {
  135. const { isHeaderRow } = useContext(TableHeaderContext);
  136. const { isFooterRow } = useContext(TableFooterContext);
  137. return (
  138. <ExpoTR
  139. // @ts-expect-error : ref type changed
  140. ref={ref}
  141. className={tableRowStyleStyle({
  142. isHeaderRow,
  143. isFooterRow,
  144. class: className,
  145. })}
  146. {...props}
  147. />
  148. );
  149. });
  150. const TableData = React.forwardRef<
  151. React.ComponentRef<typeof View | typeof Text>,
  152. ITableDataProps
  153. >(function TableData({ useRNView = false, className, ...props }, ref) {
  154. if (useRNView) {
  155. return (
  156. <View
  157. ref={ref}
  158. className={tableDataStyle({ class: className })}
  159. {...props}
  160. />
  161. );
  162. } else {
  163. return (
  164. <Text
  165. ref={ref}
  166. className={tableDataStyle({ class: className })}
  167. {...props}
  168. />
  169. );
  170. }
  171. });
  172. const TableCaption = React.forwardRef<
  173. React.ComponentRef<typeof ExpoTCaption>,
  174. ITableCaptionProps
  175. >(({ className, ...props }, ref) => {
  176. return (
  177. <ExpoTCaption
  178. // @ts-expect-error : ref type changed
  179. ref={ref}
  180. className={tableCaptionStyle({ class: className })}
  181. {...props}
  182. />
  183. );
  184. });
  185. Table.displayName = 'Table';
  186. TableHeader.displayName = 'TableHeader';
  187. TableBody.displayName = 'TableBody';
  188. TableFooter.displayName = 'TableFooter';
  189. TableHead.displayName = 'TableHead';
  190. TableRow.displayName = 'TableRow';
  191. TableData.displayName = 'TableData';
  192. TableCaption.displayName = 'TableCaption';
  193. export {
  194. Table,
  195. TableHeader,
  196. TableBody,
  197. TableFooter,
  198. TableHead,
  199. TableRow,
  200. TableData,
  201. TableCaption,
  202. };