廓形仪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.

468 lines
11 KiB

  1. 'use client';
  2. import { Text, View } from 'react-native';
  3. import React from 'react';
  4. import { createFormControl } from '@gluestack-ui/form-control';
  5. import { tva } from '@gluestack-ui/nativewind-utils/tva';
  6. import {
  7. withStyleContext,
  8. useStyleContext,
  9. } from '@gluestack-ui/nativewind-utils/withStyleContext';
  10. import { cssInterop } from 'nativewind';
  11. import type { VariantProps } from '@gluestack-ui/nativewind-utils';
  12. import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon';
  13. const SCOPE = 'FORM_CONTROL';
  14. const formControlStyle = tva({
  15. base: 'flex flex-col',
  16. variants: {
  17. size: {
  18. sm: '',
  19. md: '',
  20. lg: '',
  21. },
  22. },
  23. });
  24. const formControlErrorIconStyle = tva({
  25. base: 'text-error-700 fill-none',
  26. variants: {
  27. size: {
  28. '2xs': 'h-3 w-3',
  29. 'xs': 'h-3.5 w-3.5',
  30. 'sm': 'h-4 w-4',
  31. 'md': 'h-[18px] w-[18px]',
  32. 'lg': 'h-5 w-5',
  33. 'xl': 'h-6 w-6',
  34. },
  35. },
  36. });
  37. const formControlErrorStyle = tva({
  38. base: 'flex flex-row justify-start items-center mt-1 gap-1',
  39. });
  40. const formControlErrorTextStyle = tva({
  41. base: 'text-error-700',
  42. variants: {
  43. isTruncated: {
  44. true: 'web:truncate',
  45. },
  46. bold: {
  47. true: 'font-bold',
  48. },
  49. underline: {
  50. true: 'underline',
  51. },
  52. strikeThrough: {
  53. true: 'line-through',
  54. },
  55. size: {
  56. '2xs': 'text-2xs',
  57. 'xs': 'text-xs',
  58. 'sm': 'text-sm',
  59. 'md': 'text-base',
  60. 'lg': 'text-lg',
  61. 'xl': 'text-xl',
  62. '2xl': 'text-2xl',
  63. '3xl': 'text-3xl',
  64. '4xl': 'text-4xl',
  65. '5xl': 'text-5xl',
  66. '6xl': 'text-6xl',
  67. },
  68. sub: {
  69. true: 'text-xs',
  70. },
  71. italic: {
  72. true: 'italic',
  73. },
  74. highlight: {
  75. true: 'bg-yellow-500',
  76. },
  77. },
  78. });
  79. const formControlHelperStyle = tva({
  80. base: 'flex flex-row justify-start items-center mt-1',
  81. });
  82. const formControlHelperTextStyle = tva({
  83. base: 'text-typography-500',
  84. variants: {
  85. isTruncated: {
  86. true: 'web:truncate',
  87. },
  88. bold: {
  89. true: 'font-bold',
  90. },
  91. underline: {
  92. true: 'underline',
  93. },
  94. strikeThrough: {
  95. true: 'line-through',
  96. },
  97. size: {
  98. '2xs': 'text-2xs',
  99. 'xs': 'text-xs',
  100. 'sm': 'text-xs',
  101. 'md': 'text-sm',
  102. 'lg': 'text-base',
  103. 'xl': 'text-xl',
  104. '2xl': 'text-2xl',
  105. '3xl': 'text-3xl',
  106. '4xl': 'text-4xl',
  107. '5xl': 'text-5xl',
  108. '6xl': 'text-6xl',
  109. },
  110. sub: {
  111. true: 'text-xs',
  112. },
  113. italic: {
  114. true: 'italic',
  115. },
  116. highlight: {
  117. true: 'bg-yellow-500',
  118. },
  119. },
  120. });
  121. const formControlLabelStyle = tva({
  122. base: 'flex flex-row justify-start items-center mb-1',
  123. });
  124. const formControlLabelTextStyle = tva({
  125. base: 'font-medium text-typography-900',
  126. variants: {
  127. isTruncated: {
  128. true: 'web:truncate',
  129. },
  130. bold: {
  131. true: 'font-bold',
  132. },
  133. underline: {
  134. true: 'underline',
  135. },
  136. strikeThrough: {
  137. true: 'line-through',
  138. },
  139. size: {
  140. '2xs': 'text-2xs',
  141. 'xs': 'text-xs',
  142. 'sm': 'text-sm',
  143. 'md': 'text-base',
  144. 'lg': 'text-lg',
  145. 'xl': 'text-xl',
  146. '2xl': 'text-2xl',
  147. '3xl': 'text-3xl',
  148. '4xl': 'text-4xl',
  149. '5xl': 'text-5xl',
  150. '6xl': 'text-6xl',
  151. },
  152. sub: {
  153. true: 'text-xs',
  154. },
  155. italic: {
  156. true: 'italic',
  157. },
  158. highlight: {
  159. true: 'bg-yellow-500',
  160. },
  161. },
  162. });
  163. const formControlLabelAstrickStyle = tva({
  164. base: 'font-medium text-typography-900',
  165. variants: {
  166. isTruncated: {
  167. true: 'web:truncate',
  168. },
  169. bold: {
  170. true: 'font-bold',
  171. },
  172. underline: {
  173. true: 'underline',
  174. },
  175. strikeThrough: {
  176. true: 'line-through',
  177. },
  178. size: {
  179. '2xs': 'text-2xs',
  180. 'xs': 'text-xs',
  181. 'sm': 'text-sm',
  182. 'md': 'text-base',
  183. 'lg': 'text-lg',
  184. 'xl': 'text-xl',
  185. '2xl': 'text-2xl',
  186. '3xl': 'text-3xl',
  187. '4xl': 'text-4xl',
  188. '5xl': 'text-5xl',
  189. '6xl': 'text-6xl',
  190. },
  191. sub: {
  192. true: 'text-xs',
  193. },
  194. italic: {
  195. true: 'italic',
  196. },
  197. highlight: {
  198. true: 'bg-yellow-500',
  199. },
  200. },
  201. });
  202. type IFormControlLabelAstrickProps = React.ComponentPropsWithoutRef<
  203. typeof Text
  204. > &
  205. VariantProps<typeof formControlLabelAstrickStyle>;
  206. const FormControlLabelAstrick = React.forwardRef<
  207. React.ComponentRef<typeof Text>,
  208. IFormControlLabelAstrickProps
  209. >(function FormControlLabelAstrick({ className, ...props }, ref) {
  210. const { size: parentSize } = useStyleContext(SCOPE);
  211. return (
  212. <Text
  213. ref={ref}
  214. className={formControlLabelAstrickStyle({
  215. parentVariants: { size: parentSize },
  216. class: className,
  217. })}
  218. {...props}
  219. />
  220. );
  221. });
  222. export const UIFormControl = createFormControl({
  223. Root: withStyleContext(View, SCOPE),
  224. Error: View,
  225. ErrorText: Text,
  226. ErrorIcon: UIIcon,
  227. Label: View,
  228. LabelText: Text,
  229. LabelAstrick: FormControlLabelAstrick,
  230. Helper: View,
  231. HelperText: Text,
  232. });
  233. cssInterop(PrimitiveIcon, {
  234. className: {
  235. target: 'style',
  236. nativeStyleToProp: {
  237. height: true,
  238. width: true,
  239. fill: true,
  240. color: true,
  241. stroke: true,
  242. },
  243. },
  244. });
  245. type IFormControlProps = React.ComponentProps<typeof UIFormControl> &
  246. VariantProps<typeof formControlStyle>;
  247. const FormControl = React.forwardRef<
  248. React.ComponentRef<typeof UIFormControl>,
  249. IFormControlProps
  250. >(function FormControl({ className, size = 'md', ...props }, ref) {
  251. return (
  252. <UIFormControl
  253. ref={ref}
  254. className={formControlStyle({ size, class: className })}
  255. {...props}
  256. context={{ size }}
  257. />
  258. );
  259. });
  260. type IFormControlErrorProps = React.ComponentProps<typeof UIFormControl.Error> &
  261. VariantProps<typeof formControlErrorStyle>;
  262. const FormControlError = React.forwardRef<
  263. React.ComponentRef<typeof UIFormControl.Error>,
  264. IFormControlErrorProps
  265. >(function FormControlError({ className, ...props }, ref) {
  266. return (
  267. <UIFormControl.Error
  268. ref={ref}
  269. className={formControlErrorStyle({ class: className })}
  270. {...props}
  271. />
  272. );
  273. });
  274. type IFormControlErrorTextProps = React.ComponentProps<
  275. typeof UIFormControl.Error.Text
  276. > &
  277. VariantProps<typeof formControlErrorTextStyle>;
  278. const FormControlErrorText = React.forwardRef<
  279. React.ComponentRef<typeof UIFormControl.Error.Text>,
  280. IFormControlErrorTextProps
  281. >(function FormControlErrorText({ className, size, ...props }, ref) {
  282. const { size: parentSize } = useStyleContext(SCOPE);
  283. return (
  284. <UIFormControl.Error.Text
  285. className={formControlErrorTextStyle({
  286. parentVariants: { size: parentSize },
  287. size,
  288. class: className,
  289. })}
  290. ref={ref}
  291. {...props}
  292. />
  293. );
  294. });
  295. type IFormControlErrorIconProps = React.ComponentProps<
  296. typeof UIFormControl.Error.Icon
  297. > &
  298. VariantProps<typeof formControlErrorIconStyle> & {
  299. height?: number;
  300. width?: number;
  301. };
  302. const FormControlErrorIcon = React.forwardRef<
  303. React.ComponentRef<typeof UIFormControl.Error.Icon>,
  304. IFormControlErrorIconProps
  305. >(function FormControlErrorIcon({ className, size, ...props }, ref) {
  306. const { size: parentSize } = useStyleContext(SCOPE);
  307. if (typeof size === 'number') {
  308. return (
  309. <UIFormControl.Error.Icon
  310. ref={ref}
  311. {...props}
  312. className={formControlErrorIconStyle({ class: className })}
  313. size={size}
  314. />
  315. );
  316. } else if (
  317. (props.height !== undefined || props.width !== undefined) &&
  318. size === undefined
  319. ) {
  320. return (
  321. <UIFormControl.Error.Icon
  322. ref={ref}
  323. {...props}
  324. className={formControlErrorIconStyle({ class: className })}
  325. />
  326. );
  327. }
  328. return (
  329. <UIFormControl.Error.Icon
  330. className={formControlErrorIconStyle({
  331. parentVariants: { size: parentSize },
  332. size,
  333. class: className,
  334. })}
  335. {...props}
  336. />
  337. );
  338. });
  339. type IFormControlLabelProps = React.ComponentProps<typeof UIFormControl.Label> &
  340. VariantProps<typeof formControlLabelStyle>;
  341. const FormControlLabel = React.forwardRef<
  342. React.ComponentRef<typeof UIFormControl.Label>,
  343. IFormControlLabelProps
  344. >(function FormControlLabel({ className, ...props }, ref) {
  345. return (
  346. <UIFormControl.Label
  347. ref={ref}
  348. className={formControlLabelStyle({ class: className })}
  349. {...props}
  350. />
  351. );
  352. });
  353. type IFormControlLabelTextProps = React.ComponentProps<
  354. typeof UIFormControl.Label.Text
  355. > &
  356. VariantProps<typeof formControlLabelTextStyle>;
  357. const FormControlLabelText = React.forwardRef<
  358. React.ComponentRef<typeof UIFormControl.Label.Text>,
  359. IFormControlLabelTextProps
  360. >(function FormControlLabelText({ className, size, ...props }, ref) {
  361. const { size: parentSize } = useStyleContext(SCOPE);
  362. return (
  363. <UIFormControl.Label.Text
  364. className={formControlLabelTextStyle({
  365. parentVariants: { size: parentSize },
  366. size,
  367. class: className,
  368. })}
  369. ref={ref}
  370. {...props}
  371. />
  372. );
  373. });
  374. type IFormControlHelperProps = React.ComponentProps<
  375. typeof UIFormControl.Helper
  376. > &
  377. VariantProps<typeof formControlHelperStyle>;
  378. const FormControlHelper = React.forwardRef<
  379. React.ComponentRef<typeof UIFormControl.Helper>,
  380. IFormControlHelperProps
  381. >(function FormControlHelper({ className, ...props }, ref) {
  382. return (
  383. <UIFormControl.Helper
  384. ref={ref}
  385. className={formControlHelperStyle({
  386. class: className,
  387. })}
  388. {...props}
  389. />
  390. );
  391. });
  392. type IFormControlHelperTextProps = React.ComponentProps<
  393. typeof UIFormControl.Helper.Text
  394. > &
  395. VariantProps<typeof formControlHelperTextStyle>;
  396. const FormControlHelperText = React.forwardRef<
  397. React.ComponentRef<typeof UIFormControl.Helper.Text>,
  398. IFormControlHelperTextProps
  399. >(function FormControlHelperText({ className, size, ...props }, ref) {
  400. const { size: parentSize } = useStyleContext(SCOPE);
  401. return (
  402. <UIFormControl.Helper.Text
  403. className={formControlHelperTextStyle({
  404. parentVariants: { size: parentSize },
  405. size,
  406. class: className,
  407. })}
  408. ref={ref}
  409. {...props}
  410. />
  411. );
  412. });
  413. FormControl.displayName = 'FormControl';
  414. FormControlError.displayName = 'FormControlError';
  415. FormControlErrorText.displayName = 'FormControlErrorText';
  416. FormControlErrorIcon.displayName = 'FormControlErrorIcon';
  417. FormControlLabel.displayName = 'FormControlLabel';
  418. FormControlLabelText.displayName = 'FormControlLabelText';
  419. FormControlLabelAstrick.displayName = 'FormControlLabelAstrick';
  420. FormControlHelper.displayName = 'FormControlHelper';
  421. FormControlHelperText.displayName = 'FormControlHelperText';
  422. export {
  423. FormControl,
  424. FormControlError,
  425. FormControlErrorText,
  426. FormControlErrorIcon,
  427. FormControlLabel,
  428. FormControlLabelText,
  429. FormControlLabelAstrick,
  430. FormControlHelper,
  431. FormControlHelperText,
  432. };