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

103 lines
2.3 KiB

  1. import React from 'react';
  2. import { skeletonStyle, skeletonTextStyle } from './styles';
  3. import type { VariantProps } from '@gluestack-ui/nativewind-utils';
  4. type ISkeletonProps = React.ComponentPropsWithoutRef<'div'> &
  5. VariantProps<typeof skeletonStyle> & {
  6. startColor?: string;
  7. isLoaded?: boolean;
  8. };
  9. const Skeleton = React.forwardRef<HTMLDivElement, ISkeletonProps>(
  10. function Skeleton(
  11. {
  12. className,
  13. variant = 'rounded',
  14. children,
  15. speed = 2,
  16. startColor = 'bg-background-200',
  17. isLoaded = false,
  18. ...props
  19. },
  20. ref
  21. ) {
  22. if (!isLoaded) {
  23. return (
  24. <div
  25. ref={ref}
  26. className={`animate-pulse ${startColor} ${skeletonStyle({
  27. variant,
  28. speed,
  29. class: className,
  30. })}`}
  31. {...props}
  32. />
  33. );
  34. } else {
  35. return children;
  36. }
  37. }
  38. );
  39. type ISkeletonTextProps = React.ComponentPropsWithoutRef<'div'> &
  40. VariantProps<typeof skeletonTextStyle> & {
  41. _lines?: number;
  42. isLoaded?: boolean;
  43. startColor?: string;
  44. };
  45. const SkeletonText = React.forwardRef<HTMLDivElement, ISkeletonTextProps>(
  46. function SkeletonText(
  47. {
  48. className,
  49. _lines,
  50. isLoaded = false,
  51. startColor = 'bg-background-200',
  52. gap = 2,
  53. children,
  54. ...props
  55. },
  56. ref
  57. ) {
  58. if (!isLoaded) {
  59. if (_lines) {
  60. return (
  61. <div
  62. ref={ref}
  63. className={`flex flex-col ${skeletonTextStyle({
  64. gap,
  65. })}`}
  66. >
  67. {Array.from({ length: _lines }).map((_, index) => (
  68. <div
  69. key={index}
  70. className={`animate-pulse ${startColor} ${skeletonTextStyle({
  71. class: className,
  72. })}`}
  73. {...props}
  74. />
  75. ))}
  76. </div>
  77. );
  78. } else {
  79. return (
  80. <div
  81. ref={ref}
  82. className={`animate-pulse ${startColor} ${skeletonTextStyle({
  83. class: className,
  84. })}`}
  85. {...props}
  86. />
  87. );
  88. }
  89. } else {
  90. return children;
  91. }
  92. }
  93. );
  94. Skeleton.displayName = 'Skeleton';
  95. SkeletonText.displayName = 'SkeletonText';
  96. export { Skeleton, SkeletonText };