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

264 lines
5.9 KiB

  1. 'use client';
  2. import { createSlider } from '@gluestack-ui/slider';
  3. import { Pressable } from 'react-native';
  4. import { View } from 'react-native';
  5. import React from 'react';
  6. import { tva } from '@gluestack-ui/nativewind-utils/tva';
  7. import {
  8. withStyleContext,
  9. useStyleContext,
  10. } from '@gluestack-ui/nativewind-utils/withStyleContext';
  11. import type { VariantProps } from '@gluestack-ui/nativewind-utils';
  12. import { cssInterop } from 'nativewind';
  13. const SCOPE = 'SLIDER';
  14. const Root = withStyleContext(View, SCOPE);
  15. export const UISlider = createSlider({
  16. Root: Root,
  17. Thumb: View,
  18. Track: Pressable,
  19. FilledTrack: View,
  20. ThumbInteraction: View,
  21. });
  22. cssInterop(UISlider.Track, { className: 'style' });
  23. const sliderStyle = tva({
  24. base: 'justify-center items-center data-[disabled=true]:opacity-40 data-[disabled=true]:web:pointer-events-none',
  25. variants: {
  26. orientation: {
  27. horizontal: 'w-full',
  28. vertical: 'h-full',
  29. },
  30. size: {
  31. sm: '',
  32. md: '',
  33. lg: '',
  34. },
  35. isReversed: {
  36. true: '',
  37. false: '',
  38. },
  39. },
  40. });
  41. const sliderThumbStyle = tva({
  42. base: 'bg-primary-500 absolute rounded-full data-[focus=true]:bg-primary-600 data-[active=true]:bg-primary-600 data-[hover=true]:bg-primary-600 data-[disabled=true]:bg-primary-500 web:cursor-pointer web:data-[active=true]:outline web:data-[active=true]:outline-4 web:data-[active=true]:outline-primary-400 shadow-hard-1',
  43. parentVariants: {
  44. size: {
  45. sm: 'h-4 w-4',
  46. md: 'h-5 w-5',
  47. lg: 'h-6 w-6',
  48. },
  49. },
  50. });
  51. const sliderTrackStyle = tva({
  52. base: 'bg-background-300 rounded-lg overflow-hidden',
  53. parentVariants: {
  54. orientation: {
  55. horizontal: 'w-full',
  56. vertical: 'h-full',
  57. },
  58. isReversed: {
  59. true: '',
  60. false: '',
  61. },
  62. size: {
  63. sm: '',
  64. md: '',
  65. lg: '',
  66. },
  67. },
  68. parentCompoundVariants: [
  69. {
  70. orientation: 'horizontal',
  71. size: 'sm',
  72. class: 'h-1 flex-row',
  73. },
  74. {
  75. orientation: 'horizontal',
  76. size: 'sm',
  77. isReversed: true,
  78. class: 'h-1 flex-row-reverse',
  79. },
  80. {
  81. orientation: 'horizontal',
  82. size: 'md',
  83. class: 'h-1 flex-row',
  84. },
  85. {
  86. orientation: 'horizontal',
  87. size: 'md',
  88. isReversed: true,
  89. class: 'h-[5px] flex-row-reverse',
  90. },
  91. {
  92. orientation: 'horizontal',
  93. size: 'lg',
  94. class: 'h-1.5 flex-row',
  95. },
  96. {
  97. orientation: 'horizontal',
  98. size: 'lg',
  99. isReversed: true,
  100. class: 'h-1.5 flex-row-reverse',
  101. },
  102. {
  103. orientation: 'vertical',
  104. size: 'sm',
  105. class: 'w-1 flex-col-reverse',
  106. },
  107. {
  108. orientation: 'vertical',
  109. size: 'sm',
  110. isReversed: true,
  111. class: 'w-1 flex-col',
  112. },
  113. {
  114. orientation: 'vertical',
  115. size: 'md',
  116. class: 'w-[5px] flex-col-reverse',
  117. },
  118. {
  119. orientation: 'vertical',
  120. size: 'md',
  121. isReversed: true,
  122. class: 'w-[5px] flex-col',
  123. },
  124. {
  125. orientation: 'vertical',
  126. size: 'lg',
  127. class: 'w-1.5 flex-col-reverse',
  128. },
  129. {
  130. orientation: 'vertical',
  131. size: 'lg',
  132. isReversed: true,
  133. class: 'w-1.5 flex-col',
  134. },
  135. ],
  136. });
  137. const sliderFilledTrackStyle = tva({
  138. base: 'bg-primary-500 data-[focus=true]:bg-primary-600 data-[active=true]:bg-primary-600 data-[hover=true]:bg-primary-600',
  139. parentVariants: {
  140. orientation: {
  141. horizontal: 'h-full',
  142. vertical: 'w-full',
  143. },
  144. },
  145. });
  146. type ISliderProps = React.ComponentProps<typeof UISlider> &
  147. VariantProps<typeof sliderStyle>;
  148. const Slider = React.forwardRef<
  149. React.ComponentRef<typeof UISlider>,
  150. ISliderProps
  151. >(function Slider(
  152. {
  153. className,
  154. size = 'md',
  155. orientation = 'horizontal',
  156. isReversed = false,
  157. ...props
  158. },
  159. ref
  160. ) {
  161. return (
  162. <UISlider
  163. ref={ref}
  164. isReversed={isReversed}
  165. orientation={orientation}
  166. {...props}
  167. className={sliderStyle({
  168. orientation,
  169. isReversed,
  170. class: className,
  171. })}
  172. context={{ size, orientation, isReversed }}
  173. />
  174. );
  175. });
  176. type ISliderThumbProps = React.ComponentProps<typeof UISlider.Thumb> &
  177. VariantProps<typeof sliderThumbStyle>;
  178. const SliderThumb = React.forwardRef<
  179. React.ComponentRef<typeof UISlider.Thumb>,
  180. ISliderThumbProps
  181. >(function SliderThumb({ className, size, ...props }, ref) {
  182. const { size: parentSize } = useStyleContext(SCOPE);
  183. return (
  184. <UISlider.Thumb
  185. ref={ref}
  186. {...props}
  187. className={sliderThumbStyle({
  188. parentVariants: {
  189. size: parentSize,
  190. },
  191. size,
  192. class: className,
  193. })}
  194. />
  195. );
  196. });
  197. type ISliderTrackProps = React.ComponentProps<typeof UISlider.Track> &
  198. VariantProps<typeof sliderTrackStyle>;
  199. const SliderTrack = React.forwardRef<
  200. React.ComponentRef<typeof UISlider.Track>,
  201. ISliderTrackProps
  202. >(function SliderTrack({ className, ...props }, ref) {
  203. const {
  204. orientation: parentOrientation,
  205. size: parentSize,
  206. isReversed,
  207. } = useStyleContext(SCOPE);
  208. return (
  209. <UISlider.Track
  210. ref={ref}
  211. {...props}
  212. className={sliderTrackStyle({
  213. parentVariants: {
  214. orientation: parentOrientation,
  215. size: parentSize,
  216. isReversed,
  217. },
  218. class: className,
  219. })}
  220. />
  221. );
  222. });
  223. type ISliderFilledTrackProps = React.ComponentProps<
  224. typeof UISlider.FilledTrack
  225. > &
  226. VariantProps<typeof sliderFilledTrackStyle>;
  227. const SliderFilledTrack = React.forwardRef<
  228. React.ComponentRef<typeof UISlider.FilledTrack>,
  229. ISliderFilledTrackProps
  230. >(function SliderFilledTrack({ className, ...props }, ref) {
  231. const { orientation: parentOrientation } = useStyleContext(SCOPE);
  232. return (
  233. <UISlider.FilledTrack
  234. ref={ref}
  235. {...props}
  236. className={sliderFilledTrackStyle({
  237. parentVariants: {
  238. orientation: parentOrientation,
  239. },
  240. class: className,
  241. })}
  242. />
  243. );
  244. });
  245. export { Slider, SliderThumb, SliderTrack, SliderFilledTrack };