@unif/react-native-design 0.31.3 → 0.32.1

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.
Files changed (165) hide show
  1. package/README.md +23 -171
  2. package/lib/module/components/ui/Avatar/Avatar.js +2 -1
  3. package/lib/module/components/ui/Avatar/Avatar.js.map +1 -1
  4. package/lib/module/components/ui/Avatar/geometry.js +43 -0
  5. package/lib/module/components/ui/Avatar/geometry.js.map +1 -0
  6. package/lib/module/components/ui/Avatar/styles.js +1 -41
  7. package/lib/module/components/ui/Avatar/styles.js.map +1 -1
  8. package/lib/module/components/ui/AvatarGroup/AvatarGroup.js +1 -1
  9. package/lib/module/components/ui/AvatarGroup/AvatarGroup.js.map +1 -1
  10. package/lib/module/components/ui/CircularProgress/CircularProgress.js +14 -25
  11. package/lib/module/components/ui/CircularProgress/CircularProgress.js.map +1 -1
  12. package/lib/module/components/ui/CircularProgress/normalizeCircularProgress.js.map +1 -1
  13. package/lib/module/components/ui/CircularProgress/styles.js +24 -0
  14. package/lib/module/components/ui/CircularProgress/styles.js.map +1 -0
  15. package/lib/module/components/ui/Pulse/PulseDot.js +5 -5
  16. package/lib/module/components/ui/Pulse/PulseDot.js.map +1 -1
  17. package/lib/module/components/ui/Pulse/constants.js +15 -0
  18. package/lib/module/components/ui/Pulse/constants.js.map +1 -0
  19. package/lib/module/components/ui/Pulse/usePulse.js +4 -62
  20. package/lib/module/components/ui/Pulse/usePulse.js.map +1 -1
  21. package/lib/module/components/ui/Skeleton/Skeleton.js +6 -2
  22. package/lib/module/components/ui/Skeleton/Skeleton.js.map +1 -1
  23. package/lib/module/components/ui/Skeleton/constants.js +9 -0
  24. package/lib/module/components/ui/Skeleton/constants.js.map +1 -0
  25. package/lib/module/components/ui/TextField/TextFieldBase.js +21 -4
  26. package/lib/module/components/ui/TextField/TextFieldBase.js.map +1 -1
  27. package/lib/module/components/ui/TextField/constants.js +7 -0
  28. package/lib/module/components/ui/TextField/constants.js.map +1 -0
  29. package/lib/module/components/ui/TextField/styles.js +10 -2
  30. package/lib/module/components/ui/TextField/styles.js.map +1 -1
  31. package/lib/module/components/ui/TextField/useMultilineLayout.js +18 -0
  32. package/lib/module/components/ui/TextField/useMultilineLayout.js.map +1 -0
  33. package/lib/module/components/ui/TextField/useMultilineLayout.web.js +44 -0
  34. package/lib/module/components/ui/TextField/useMultilineLayout.web.js.map +1 -0
  35. package/lib/module/components/ui/Thumbnail/Thumbnail.js +13 -6
  36. package/lib/module/components/ui/Thumbnail/Thumbnail.js.map +1 -1
  37. package/lib/module/components/ui/Thumbnail/constants.js +22 -0
  38. package/lib/module/components/ui/Thumbnail/constants.js.map +1 -0
  39. package/lib/module/components/ui/Thumbnail/normalize.js +30 -1
  40. package/lib/module/components/ui/Thumbnail/normalize.js.map +1 -1
  41. package/lib/module/components/ui/Thumbnail/styles.js +5 -28
  42. package/lib/module/components/ui/Thumbnail/styles.js.map +1 -1
  43. package/lib/module/components/ui/index.js.map +1 -1
  44. package/lib/module/components/ui/shared/pulse/constants.js +5 -0
  45. package/lib/module/components/ui/shared/pulse/constants.js.map +1 -0
  46. package/lib/module/components/ui/{Pulse → shared/pulse}/normalizePulseOptions.js +2 -12
  47. package/lib/module/components/ui/shared/pulse/normalizePulseOptions.js.map +1 -0
  48. package/lib/module/components/ui/shared/pulse/types.js +2 -0
  49. package/lib/module/components/ui/shared/pulse/types.js.map +1 -0
  50. package/lib/module/components/ui/shared/pulse/usePulseAnimation.js +30 -0
  51. package/lib/module/components/ui/shared/pulse/usePulseAnimation.js.map +1 -0
  52. package/lib/module/components/ui/{Pulse → shared/pulse}/usePulseDriver.js +1 -1
  53. package/lib/module/components/ui/shared/pulse/usePulseDriver.js.map +1 -0
  54. package/lib/module/components/ui/{Pulse → shared/pulse}/usePulseDriver.web.js +2 -17
  55. package/lib/module/components/ui/shared/pulse/usePulseDriver.web.js.map +1 -0
  56. package/lib/typescript/src/components/ui/Avatar/Avatar.d.ts.map +1 -1
  57. package/lib/typescript/src/components/ui/Avatar/geometry.d.ts +7 -0
  58. package/lib/typescript/src/components/ui/Avatar/geometry.d.ts.map +1 -0
  59. package/lib/typescript/src/components/ui/Avatar/styles.d.ts +1 -9
  60. package/lib/typescript/src/components/ui/Avatar/styles.d.ts.map +1 -1
  61. package/lib/typescript/src/components/ui/Avatar/types.d.ts +7 -2
  62. package/lib/typescript/src/components/ui/Avatar/types.d.ts.map +1 -1
  63. package/lib/typescript/src/components/ui/CircularProgress/CircularProgress.d.ts.map +1 -1
  64. package/lib/typescript/src/components/ui/CircularProgress/normalizeCircularProgress.d.ts +2 -14
  65. package/lib/typescript/src/components/ui/CircularProgress/normalizeCircularProgress.d.ts.map +1 -1
  66. package/lib/typescript/src/components/ui/CircularProgress/styles.d.ts +19 -0
  67. package/lib/typescript/src/components/ui/CircularProgress/styles.d.ts.map +1 -0
  68. package/lib/typescript/src/components/ui/CircularProgress/types.d.ts +17 -2
  69. package/lib/typescript/src/components/ui/CircularProgress/types.d.ts.map +1 -1
  70. package/lib/typescript/src/components/ui/Pulse/PulseDot.d.ts.map +1 -1
  71. package/lib/typescript/src/components/ui/Pulse/constants.d.ts +4 -0
  72. package/lib/typescript/src/components/ui/Pulse/constants.d.ts.map +1 -0
  73. package/lib/typescript/src/components/ui/Pulse/types.d.ts +6 -6
  74. package/lib/typescript/src/components/ui/Pulse/types.d.ts.map +1 -1
  75. package/lib/typescript/src/components/ui/Pulse/usePulse.d.ts +0 -9
  76. package/lib/typescript/src/components/ui/Pulse/usePulse.d.ts.map +1 -1
  77. package/lib/typescript/src/components/ui/Skeleton/Skeleton.d.ts.map +1 -1
  78. package/lib/typescript/src/components/ui/Skeleton/constants.d.ts +3 -0
  79. package/lib/typescript/src/components/ui/Skeleton/constants.d.ts.map +1 -0
  80. package/lib/typescript/src/components/ui/Skeleton/types.d.ts +2 -2
  81. package/lib/typescript/src/components/ui/Skeleton/types.d.ts.map +1 -1
  82. package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts.map +1 -1
  83. package/lib/typescript/src/components/ui/TextField/constants.d.ts +4 -0
  84. package/lib/typescript/src/components/ui/TextField/constants.d.ts.map +1 -0
  85. package/lib/typescript/src/components/ui/TextField/styles.d.ts +6 -0
  86. package/lib/typescript/src/components/ui/TextField/styles.d.ts.map +1 -1
  87. package/lib/typescript/src/components/ui/TextField/types.d.ts +36 -11
  88. package/lib/typescript/src/components/ui/TextField/types.d.ts.map +1 -1
  89. package/lib/typescript/src/components/ui/TextField/useMultilineLayout.d.ts +4 -0
  90. package/lib/typescript/src/components/ui/TextField/useMultilineLayout.d.ts.map +1 -0
  91. package/lib/typescript/src/components/ui/TextField/useMultilineLayout.web.d.ts +4 -0
  92. package/lib/typescript/src/components/ui/TextField/useMultilineLayout.web.d.ts.map +1 -0
  93. package/lib/typescript/src/components/ui/Textarea/types.d.ts +4 -2
  94. package/lib/typescript/src/components/ui/Textarea/types.d.ts.map +1 -1
  95. package/lib/typescript/src/components/ui/Thumbnail/Thumbnail.d.ts.map +1 -1
  96. package/lib/typescript/src/components/ui/Thumbnail/constants.d.ts +4 -0
  97. package/lib/typescript/src/components/ui/Thumbnail/constants.d.ts.map +1 -0
  98. package/lib/typescript/src/components/ui/Thumbnail/index.d.ts +1 -1
  99. package/lib/typescript/src/components/ui/Thumbnail/index.d.ts.map +1 -1
  100. package/lib/typescript/src/components/ui/Thumbnail/normalize.d.ts +2 -6
  101. package/lib/typescript/src/components/ui/Thumbnail/normalize.d.ts.map +1 -1
  102. package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts +9 -8
  103. package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts.map +1 -1
  104. package/lib/typescript/src/components/ui/Thumbnail/types.d.ts +23 -5
  105. package/lib/typescript/src/components/ui/Thumbnail/types.d.ts.map +1 -1
  106. package/lib/typescript/src/components/ui/index.d.ts +1 -1
  107. package/lib/typescript/src/components/ui/index.d.ts.map +1 -1
  108. package/lib/typescript/src/components/ui/shared/pulse/constants.d.ts +2 -0
  109. package/lib/typescript/src/components/ui/shared/pulse/constants.d.ts.map +1 -0
  110. package/lib/typescript/src/components/ui/shared/pulse/normalizePulseOptions.d.ts +7 -0
  111. package/lib/typescript/src/components/ui/shared/pulse/normalizePulseOptions.d.ts.map +1 -0
  112. package/lib/typescript/src/components/ui/shared/pulse/types.d.ts +17 -0
  113. package/lib/typescript/src/components/ui/shared/pulse/types.d.ts.map +1 -0
  114. package/lib/typescript/src/components/ui/shared/pulse/usePulseAnimation.d.ts +8 -0
  115. package/lib/typescript/src/components/ui/shared/pulse/usePulseAnimation.d.ts.map +1 -0
  116. package/lib/typescript/src/components/ui/{Pulse → shared/pulse}/usePulseDriver.d.ts +1 -1
  117. package/lib/typescript/src/components/ui/shared/pulse/usePulseDriver.d.ts.map +1 -0
  118. package/lib/typescript/src/components/ui/shared/pulse/usePulseDriver.web.d.ts +7 -0
  119. package/lib/typescript/src/components/ui/shared/pulse/usePulseDriver.web.d.ts.map +1 -0
  120. package/package.json +2 -2
  121. package/src/components/ui/Avatar/Avatar.tsx +2 -6
  122. package/src/components/ui/Avatar/geometry.ts +30 -0
  123. package/src/components/ui/Avatar/styles.ts +2 -30
  124. package/src/components/ui/Avatar/types.ts +8 -2
  125. package/src/components/ui/AvatarGroup/AvatarGroup.tsx +1 -1
  126. package/src/components/ui/CircularProgress/CircularProgress.tsx +20 -26
  127. package/src/components/ui/CircularProgress/normalizeCircularProgress.ts +7 -15
  128. package/src/components/ui/CircularProgress/styles.ts +13 -0
  129. package/src/components/ui/CircularProgress/types.ts +19 -2
  130. package/src/components/ui/Pulse/PulseDot.tsx +6 -5
  131. package/src/components/ui/Pulse/constants.ts +14 -0
  132. package/src/components/ui/Pulse/types.ts +6 -6
  133. package/src/components/ui/Pulse/usePulse.ts +4 -81
  134. package/src/components/ui/Skeleton/Skeleton.tsx +6 -6
  135. package/src/components/ui/Skeleton/constants.ts +8 -0
  136. package/src/components/ui/Skeleton/types.ts +2 -2
  137. package/src/components/ui/TextField/TextFieldBase.tsx +28 -4
  138. package/src/components/ui/TextField/constants.ts +6 -0
  139. package/src/components/ui/TextField/styles.ts +8 -2
  140. package/src/components/ui/TextField/types.ts +41 -11
  141. package/src/components/ui/TextField/useMultilineLayout.ts +20 -0
  142. package/src/components/ui/TextField/useMultilineLayout.web.ts +59 -0
  143. package/src/components/ui/Textarea/types.ts +9 -6
  144. package/src/components/ui/Thumbnail/Thumbnail.tsx +19 -5
  145. package/src/components/ui/Thumbnail/constants.ts +24 -0
  146. package/src/components/ui/Thumbnail/index.ts +1 -0
  147. package/src/components/ui/Thumbnail/normalize.ts +38 -19
  148. package/src/components/ui/Thumbnail/styles.ts +6 -17
  149. package/src/components/ui/Thumbnail/types.ts +27 -5
  150. package/src/components/ui/index.ts +1 -0
  151. package/src/components/ui/shared/pulse/constants.ts +2 -0
  152. package/src/components/ui/shared/pulse/normalizePulseOptions.ts +48 -0
  153. package/src/components/ui/shared/pulse/types.ts +18 -0
  154. package/src/components/ui/shared/pulse/usePulseAnimation.ts +29 -0
  155. package/src/components/ui/{Pulse → shared/pulse}/usePulseDriver.ts +2 -2
  156. package/src/components/ui/{Pulse → shared/pulse}/usePulseDriver.web.ts +4 -19
  157. package/lib/module/components/ui/Pulse/normalizePulseOptions.js.map +0 -1
  158. package/lib/module/components/ui/Pulse/usePulseDriver.js.map +0 -1
  159. package/lib/module/components/ui/Pulse/usePulseDriver.web.js.map +0 -1
  160. package/lib/typescript/src/components/ui/Pulse/normalizePulseOptions.d.ts +0 -32
  161. package/lib/typescript/src/components/ui/Pulse/normalizePulseOptions.d.ts.map +0 -1
  162. package/lib/typescript/src/components/ui/Pulse/usePulseDriver.d.ts.map +0 -1
  163. package/lib/typescript/src/components/ui/Pulse/usePulseDriver.web.d.ts +0 -18
  164. package/lib/typescript/src/components/ui/Pulse/usePulseDriver.web.d.ts.map +0 -1
  165. package/src/components/ui/Pulse/normalizePulseOptions.ts +0 -76
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMultilineLayout.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/TextField/useMultilineLayout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAErE,yDAAyD;AACzD,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,SAAS,GACV,EAAE,oBAAoB,GAAG,eAAe,CAYxC"}
@@ -0,0 +1,4 @@
1
+ import type { MultilineLayout, MultilineLayoutInput } from './types';
2
+ /** RNW 的 contentSize 使用 scrollHeight,固定高度会阻止缩短,须临时解除高度后测量。 */
3
+ export declare function useMultilineLayout({ enabled, value, minHeight, maxHeight, fontSize, placeholder, inputRef, }: MultilineLayoutInput): MultilineLayout;
4
+ //# sourceMappingURL=useMultilineLayout.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMultilineLayout.web.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/TextField/useMultilineLayout.web.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EAErB,MAAM,SAAS,CAAC;AAEjB,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,KAAK,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,WAAW,EACX,QAAQ,GACT,EAAE,oBAAoB,GAAG,eAAe,CAyCxC"}
@@ -6,10 +6,12 @@ import type { RemovedTextInputProps, TextFieldCommonProps, TextFieldValueProps }
6
6
  * 内部固定 `multiline=true`;高度在 `[minHeight, maxHeight]` 之间根据内容增长。
7
7
  * 继承除 `style` / `multiline` / `numberOfLines` 之外的 RN `TextInputProps`。
8
8
  */
9
- export type TextareaProps = Omit<TextInputProps, RemovedTextInputProps> & TextFieldCommonProps & TextFieldValueProps & {
9
+ export type TextareaProps = Omit<TextInputProps, RemovedTextInputProps> & TextFieldCommonProps & TextFieldValueProps & TextareaHeightProps;
10
+ interface TextareaHeightProps {
10
11
  /** 最小高度,默认 96(约 5 行) */
11
12
  minHeight?: number;
12
13
  /** 最大高度(超过后内部滚动),默认不限制 */
13
14
  maxHeight?: number;
14
- };
15
+ }
16
+ export {};
15
17
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Textarea/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,qBAAqB,CAAC,GACrE,oBAAoB,GACpB,mBAAmB,GAAG;IACpB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Textarea/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,qBAAqB,CAAC,GACrE,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,CAAC;AAEtB,UAAU,mBAAmB;IAC3B,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"Thumbnail.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/Thumbnail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AASzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAM9C;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA6ElE"}
1
+ {"version":3,"file":"Thumbnail.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/Thumbnail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAYzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAM9C;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAwFlE"}
@@ -0,0 +1,4 @@
1
+ import type { ThumbnailDimensions, ThumbnailSize } from './types';
2
+ export declare const THUMBNAIL_DIMENSIONS: Readonly<Record<ThumbnailSize, Required<ThumbnailDimensions>>>;
3
+ export declare const RESERVED_IMAGE_STYLE_KEYS: readonly ["position", "top", "right", "bottom", "left", "width", "height", "minWidth", "minHeight", "maxWidth", "maxHeight"];
4
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CACzC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAKrD,CAAC;AAEF,eAAO,MAAM,yBAAyB,8HAY5B,CAAC"}
@@ -1,3 +1,3 @@
1
1
  export { Thumbnail } from './Thumbnail';
2
- export type { ThumbnailImageStyle, ThumbnailProps, ThumbnailSize, } from './types';
2
+ export type { ThumbnailDimensions, ThumbnailImageStyle, ThumbnailProps, ThumbnailSize, } from './types';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,SAAS,CAAC"}
@@ -1,13 +1,9 @@
1
1
  import type { StyleProp } from 'react-native';
2
- import type { ThumbnailImageStyle } from './types';
3
- type SanitizedThumbnailImageStyle = {
4
- style: ThumbnailImageStyle;
5
- diagnostics: readonly string[];
6
- };
2
+ import type { NormalizedThumbnailDimensions, SanitizedThumbnailImageStyle, ThumbnailImageStyle } from './types';
3
+ export declare function normalizeThumbnailDimensions(size: unknown): NormalizedThumbnailDimensions;
7
4
  /**
8
5
  * 先 flatten 再复制允许字段,兼容 registered / array style,同时不修改 caller。
9
6
  * 任意异常或非对象产物都失败关闭,避免宽类型 JS 值穿透到原生 Image。
10
7
  */
11
8
  export declare function sanitizeThumbnailImageStyle(style: StyleProp<ThumbnailImageStyle> | undefined): SanitizedThumbnailImageStyle;
12
- export {};
13
9
  //# sourceMappingURL=normalize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAgBnD,KAAK,4BAA4B,GAAG;IAClC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC,CAAC;AAYF;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,SAAS,CAAC,mBAAmB,CAAC,GAAG,SAAS,GAChD,4BAA4B,CAsC9B"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAGjB,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,OAAO,GACZ,6BAA6B,CA6B/B;AAYD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,SAAS,CAAC,mBAAmB,CAAC,GAAG,SAAS,GAChD,4BAA4B,CAsC9B"}
@@ -1,5 +1,4 @@
1
1
  import { type ColorTokens } from '../../../theme';
2
- import type { ThumbnailSize } from './types';
3
2
  /** Thumbnail 静态样式 ——
4
3
  * - `visualFrame`:固定尺寸、裁切、加载失败 placeholder
5
4
  * - `ring`:始终存在的 2pt visual overlay,selected 只切颜色 */
@@ -11,12 +10,14 @@ export declare const makeStyles: (c: ColorTokens) => Readonly<{
11
10
  ring: {
12
11
  borderWidth: number;
13
12
  };
13
+ fallback: {
14
+ alignItems: "center";
15
+ justifyContent: "center";
16
+ position: "absolute";
17
+ left: 0;
18
+ right: 0;
19
+ top: 0;
20
+ bottom: 0;
21
+ };
14
22
  }>;
15
- /** Thumbnail size 阶梯 —— width / height / borderRadius 全 r() 缩放。
16
- * 新增 size 在 types.ts 加 union + 这里加 case,两处同步。 */
17
- export declare const sizingFor: (size: ThumbnailSize) => {
18
- width: number;
19
- height: number;
20
- borderRadius: number;
21
- };
22
23
  //# sourceMappingURL=styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/styles.ts"],"names":[],"mappings":"AACA,OAAO,EAAK,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;sDAEsD;AACtD,eAAO,MAAM,UAAU,GAAI,GAAG,WAAW;;;;;;;;EASrC,CAAC;AAEL;kDACkD;AAClD,eAAO,MAAM,SAAS,GAAI,MAAM,aAAa;;;;CAW5C,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/styles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;sDAEsD;AACtD,eAAO,MAAM,UAAU,GAAI,GAAG,WAAW;;;;;;;;;;;;;;;;;EAcrC,CAAC"}
@@ -1,9 +1,24 @@
1
+ import type { ReactNode } from 'react';
1
2
  import type { ImageProps, ImageSourcePropType, ImageStyle, StyleProp, ViewStyle } from 'react-native';
2
- /** 缩略图尺寸阶梯 —— 跨场景统一,新增 size 在这里 + sizingFor.ts 同步。
3
+ /** 缩略图尺寸阶梯 —— 跨场景统一,新增阶梯在这里与 constants.ts 同步。
3
4
  * - sm:64×40 chat 行内、列表二级图缩略
4
5
  * - md:113×67 NewsList / NewsArea 公告右侧缩略(默认)
5
6
  * - lg:160×96 详情顶部 hero 小图、卡片头图缩略 */
6
7
  export type ThumbnailSize = 'sm' | 'md' | 'lg';
8
+ /** 已计算好的 RN 布局尺寸;组件不再调用 r() 缩放。 */
9
+ export interface ThumbnailDimensions {
10
+ width: number;
11
+ height: number;
12
+ borderRadius?: number;
13
+ }
14
+ export interface NormalizedThumbnailDimensions {
15
+ dimensions: Required<ThumbnailDimensions>;
16
+ diagnostics: readonly string[];
17
+ }
18
+ export interface SanitizedThumbnailImageStyle {
19
+ style: ThumbnailImageStyle;
20
+ diagnostics: readonly string[];
21
+ }
7
22
  export type ThumbnailImageStyle = Omit<ImageStyle, 'position' | 'top' | 'right' | 'bottom' | 'left' | 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'>;
8
23
  type ThumbnailSource = {
9
24
  /** 远程 URL(http/https/data URI),运行时 trim 后必须非空。 */
@@ -14,9 +29,11 @@ type ThumbnailSource = {
14
29
  source: ImageSourcePropType;
15
30
  uri?: never;
16
31
  };
17
- export type ThumbnailProps = ThumbnailSource & {
18
- /** 视觉尺寸阶梯,默认 'md'。 */
19
- size?: ThumbnailSize;
32
+ interface ThumbnailCommonProps {
33
+ /** 原三档或实际图像框尺寸,默认 md;非法对象整体回退 md。 */
34
+ size?: ThumbnailSize | Readonly<ThumbnailDimensions>;
35
+ /** 无有效 source 或当前图片失败时居中显示;加载中不显示。 */
36
+ fallback?: ReactNode;
20
37
  /** 选中态:在固定 visual frame 内显示 2pt 品牌色 ring。 */
21
38
  selected?: boolean;
22
39
  /** 完整外部布局样式,只落到稳定根 View。 */
@@ -29,6 +46,7 @@ export type ThumbnailProps = ThumbnailSource & {
29
46
  accessibilityLabel?: string;
30
47
  /** E2E / 测试定位,只落到外层 layout View。 */
31
48
  testID?: string;
32
- };
49
+ }
50
+ export type ThumbnailProps = ThumbnailSource & ThumbnailCommonProps;
33
51
  export {};
34
52
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB;;;sCAGsC;AACtC,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,UAAU,EACR,UAAU,GACV,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,CACd,CAAC;AAEF,KAAK,eAAe,GAChB;IACE,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB,GACD;IACE,qEAAqE;IACrE,MAAM,EAAE,mBAAmB,CAAC;IAC5B,GAAG,CAAC,EAAE,KAAK,CAAC;CACb,CAAC;AAEN,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG;IAC7C,sBAAsB;IACtB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,4DAA4D;IAC5D,UAAU,CAAC,EAAE,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAC5C,yCAAyC;IACzC,UAAU,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IACnD,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Thumbnail/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EACV,UAAU,EACV,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB;;;sCAGsC;AACtC,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,mCAAmC;AACnC,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAC1C,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,mBAAmB,CAAC;IAC3B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,UAAU,EACR,UAAU,GACV,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,CACd,CAAC;AAEF,KAAK,eAAe,GAChB;IACE,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB,GACD;IACE,qEAAqE;IACrE,MAAM,EAAE,mBAAmB,CAAC;IAC5B,GAAG,CAAC,EAAE,KAAK,CAAC;CACb,CAAC;AAEN,UAAU,oBAAoB;IAC5B,qCAAqC;IACrC,IAAI,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACrD,sCAAsC;IACtC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,4DAA4D;IAC5D,UAAU,CAAC,EAAE,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAC5C,yCAAyC;IACzC,UAAU,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IACnD,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,oBAAoB,CAAC"}
@@ -75,7 +75,7 @@ export type { TagProps, TagSize, TagVariant } from './Tag';
75
75
  export { Textarea } from './Textarea';
76
76
  export type { TextareaProps } from './Textarea';
77
77
  export { Thumbnail } from './Thumbnail';
78
- export type { ThumbnailImageStyle, ThumbnailProps, ThumbnailSize, } from './Thumbnail';
78
+ export type { ThumbnailImageStyle, ThumbnailDimensions, ThumbnailProps, ThumbnailSize, } from './Thumbnail';
79
79
  export { toast, ToastHost } from './Toast';
80
80
  export type { ToastEntry, ToastHostProps, ToastInput, ToastKind, ToastPosition, } from './Toast';
81
81
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,GACd,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,SAAS,GACV,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EACV,UAAU,EACV,uBAAuB,EACvB,eAAe,EACf,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,IAAI,eAAe,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EACV,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3C,YAAY,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const MAX_TIMER: number;
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/ui/shared/pulse/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,SAAS,QAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { PulseOptions } from '../../Pulse/types';
2
+ import type { NormalizedPulseOptions, PulseDefaults } from './types';
3
+ /** 共用的参数校验:非法字段采用所属组件默认值并报告诊断,不夹值或取整。 */
4
+ export declare function normalizePulseOptions(input: PulseOptions | undefined, defaults: Readonly<PulseDefaults>): NormalizedPulseOptions;
5
+ /** driver 是否应当启动循环。静态或系统开启减弱动效时都不启动。 */
6
+ export declare const shouldAnimatePulse: (options: NormalizedPulseOptions, reducedMotion: boolean) => boolean;
7
+ //# sourceMappingURL=normalizePulseOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizePulseOptions.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/ui/shared/pulse/normalizePulseOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EACV,sBAAsB,EACtB,aAAa,EAEd,MAAM,SAAS,CAAC;AAGjB,yCAAyC;AACzC,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,YAAY,YAAK,EACxB,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,GAChC,sBAAsB,CA6BxB;AAED,wCAAwC;AACxC,eAAO,MAAM,kBAAkB,GAC7B,SAAS,sBAAsB,EAC/B,eAAe,OAAO,KACrB,OAA8C,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface PulseDefaults {
2
+ duration: number;
3
+ delay: number;
4
+ from: number;
5
+ to: number;
6
+ }
7
+ export interface PulseDiagnostic {
8
+ field: keyof PulseDefaults;
9
+ received: unknown;
10
+ fallback: number;
11
+ }
12
+ export interface NormalizedPulseOptions extends PulseDefaults {
13
+ /** 两端相等 —— 没有可播的动画,driver 直接停在 `to`。 */
14
+ isStatic: boolean;
15
+ diagnostics: readonly PulseDiagnostic[];
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/ui/shared/pulse/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,aAAa,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D,wCAAwC;IACxC,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;CACzC"}
@@ -0,0 +1,8 @@
1
+ import type { createLogger } from '../../../../utils/logger';
2
+ import type { PulseOptions } from '../../Pulse/types';
3
+ import type { PulseDefaults } from './types';
4
+ /** 共享参数解释与平台驱动;默认值和诊断 scope 由所属组件交付。 */
5
+ export declare function usePulseAnimation({ duration, delay, from, to }: PulseOptions | undefined, defaults: Readonly<PulseDefaults>, log: ReturnType<typeof createLogger>): import("react-native-reanimated/lib/typescript/hook/commonTypes").AnimatedStyleHandle<{
6
+ opacity: number;
7
+ }>;
8
+ //# sourceMappingURL=usePulseAnimation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePulseAnimation.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/ui/shared/pulse/usePulseAnimation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7C,wCAAwC;AACxC,wBAAgB,iBAAiB,CAC/B,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,YAAY,YAAK,EAChD,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,EACjC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC;;GAiBrC"}
@@ -1,4 +1,4 @@
1
- import type { NormalizedPulseOptions } from './normalizePulseOptions';
1
+ import type { NormalizedPulseOptions } from './types';
2
2
  /**
3
3
  * native Pulse driver —— reanimated 4 worklet,整个动画在 UI 线程跑、不占 JS 桥。
4
4
  *
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePulseDriver.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/ui/shared/pulse/usePulseDriver.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,sBAAsB;;GA4B7D"}
@@ -0,0 +1,7 @@
1
+ import type { NormalizedPulseOptions } from './types';
2
+ /** Web 由 CSS 补间,timer 只按归一化后的半周期切换透明度;每个实例独立释放。 */
3
+ export declare function usePulseDriver(options: NormalizedPulseOptions): {
4
+ transition?: string | undefined;
5
+ opacity: number;
6
+ };
7
+ //# sourceMappingURL=usePulseDriver.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePulseDriver.web.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/ui/shared/pulse/usePulseDriver.web.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,OAAO,EAAE,sBAAsB;;;EA4C7D"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unif/react-native-design",
3
- "version": "0.31.3",
4
- "description": "Unif 设计系统:theme + icons + utils + components",
3
+ "version": "0.32.1",
4
+ "description": "Unif React Native 设计系统:基础组件、主题、字体和图标",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
7
7
  "sideEffects": [
@@ -3,12 +3,8 @@ import { Text, View } from 'react-native';
3
3
  import { scaleFontMetric, useColors, useFontScale } from '../../../theme';
4
4
  import { resolveImageSource } from '../../../utils/imageSource';
5
5
  import { ImageAttempt } from '../shared/ImageAttempt';
6
- import {
7
- paletteFor,
8
- resolveAvatarBorderRadius,
9
- sizingFor,
10
- styles,
11
- } from './styles';
6
+ import { paletteFor, styles } from './styles';
7
+ import { resolveAvatarBorderRadius, sizingFor } from './geometry';
12
8
  import type { AvatarProps } from './types';
13
9
 
14
10
  /**
@@ -0,0 +1,30 @@
1
+ import { avatar, radius, rf } from '../../../theme';
2
+ import type { AvatarGeometry, AvatarShape, AvatarSize } from './types';
3
+
4
+ /** Avatar 尺寸推导:5 档 size → { box, fs }。box 走 avatar.<size> token。
5
+ * 新增 size 在 types.ts 加 union + 这里加 case + tokens.ts 补 avatar.<key>。 */
6
+ export function sizingFor(size: AvatarSize): AvatarGeometry {
7
+ switch (size) {
8
+ case 'xs':
9
+ return { box: avatar.xs, fs: rf(10) };
10
+ case 'sm':
11
+ return { box: avatar.sm, fs: rf(12) };
12
+ case 'md':
13
+ return { box: avatar.md, fs: rf(13) };
14
+ case 'lg':
15
+ return { box: avatar.lg, fs: rf(15) };
16
+ case 'xl':
17
+ return { box: avatar.xl, fs: rf(20) };
18
+ }
19
+ }
20
+
21
+ /** circle 保留直径一半的现有视觉;square 按尺寸使用既有圆角 token。 */
22
+ export function resolveAvatarBorderRadius(
23
+ size: AvatarSize,
24
+ shape: AvatarShape
25
+ ): number {
26
+ if (shape === 'circle') return sizingFor(size).box / 2;
27
+ if (size === 'xs' || size === 'sm') return radius.xs;
28
+ if (size === 'xl') return radius.md;
29
+ return radius.sm;
30
+ }
@@ -1,6 +1,6 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import { avatar, fw, radius, rf, type ColorTokens } from '../../../theme';
3
- import type { AvatarShape, AvatarSize, AvatarVariant } from './types';
2
+ import { fw, type ColorTokens } from '../../../theme';
3
+ import type { AvatarVariant } from './types';
4
4
 
5
5
  /** Avatar 静态 base —— 容器圆角 / 尺寸由 resolver 派生。 */
6
6
  export const styles = StyleSheet.create({
@@ -19,34 +19,6 @@ export const styles = StyleSheet.create({
19
19
  },
20
20
  });
21
21
 
22
- /** Avatar 尺寸推导:5 档 size → { box, fs }。box 走 avatar.<size> token。
23
- * 新增 size 在 types.ts 加 union + 这里加 case + tokens.ts 补 avatar.<key>。 */
24
- export function sizingFor(size: AvatarSize): { box: number; fs: number } {
25
- switch (size) {
26
- case 'xs':
27
- return { box: avatar.xs, fs: rf(10) };
28
- case 'sm':
29
- return { box: avatar.sm, fs: rf(12) };
30
- case 'md':
31
- return { box: avatar.md, fs: rf(13) };
32
- case 'lg':
33
- return { box: avatar.lg, fs: rf(15) };
34
- case 'xl':
35
- return { box: avatar.xl, fs: rf(20) };
36
- }
37
- }
38
-
39
- /** circle 保留直径一半的现有视觉;square 按尺寸使用既有圆角 token。 */
40
- export function resolveAvatarBorderRadius(
41
- size: AvatarSize,
42
- shape: AvatarShape
43
- ): number {
44
- if (shape === 'circle') return sizingFor(size).box / 2;
45
- if (size === 'xs' || size === 'sm') return radius.xs;
46
- if (size === 'xl') return radius.md;
47
- return radius.sm;
48
- }
49
-
50
22
  /** Avatar 配色推导:4 种 variant → { bg, fg }。签名与 Tag/Button 的 paletteFor 一致。 */
51
23
  export function paletteFor(
52
24
  variant: AvatarVariant,
@@ -15,7 +15,7 @@ export type AvatarShape = 'circle' | 'square';
15
15
  */
16
16
  export type AvatarVariant = 'brand' | 'info' | 'soft' | 'neutral';
17
17
 
18
- export type AvatarProps = {
18
+ export interface AvatarProps {
19
19
  /**
20
20
  * 头像里显示的文字(建议 1-2 字符)。
21
21
  * 同时作为 a11y label(screen reader 朗读);source 加载失败时回退展示。
@@ -40,4 +40,10 @@ export type AvatarProps = {
40
40
  style?: StyleProp<ViewStyle>;
41
41
  /** E2E / 测试定位 */
42
42
  testID?: string;
43
- };
43
+ }
44
+
45
+ /** 头像族内部几何,不进入公共 barrel。 */
46
+ export interface AvatarGeometry {
47
+ box: number;
48
+ fs: number;
49
+ }
@@ -11,7 +11,7 @@ import {
11
11
  import { createLogger } from '../../../utils/logger';
12
12
  import { childTestID } from '../../../utils/testID';
13
13
  import { Avatar } from '../Avatar';
14
- import { resolveAvatarBorderRadius, sizingFor } from '../Avatar/styles';
14
+ import { resolveAvatarBorderRadius, sizingFor } from '../Avatar/geometry';
15
15
  import { normalizeNonBlankText } from '../shared/accessibilityName';
16
16
  import { resolveAvatarGroupLayout } from './layout';
17
17
  import { normalizeAvatarGroup } from './normalize';
@@ -1,27 +1,17 @@
1
1
  import { Text, View } from 'react-native';
2
- import type { TextStyle, ViewStyle } from 'react-native';
3
2
  import Svg, { Circle } from 'react-native-svg';
4
- import { r, type, useColors } from '../../../theme';
3
+ import {
4
+ r,
5
+ type,
6
+ useColors,
7
+ useFontScale,
8
+ scaleFontMetric,
9
+ } from '../../../theme';
5
10
  import { A11Y_HIDDEN_PROPS } from '../shared/a11y';
6
11
  import { normalizeCircularProgress } from './normalizeCircularProgress';
7
12
  import type { CircularProgressProps } from './types';
8
13
 
9
- const OUTER_CENTER_STYLE = {
10
- alignItems: 'center',
11
- justifyContent: 'center',
12
- } as const satisfies ViewStyle;
13
-
14
- const VISUAL_CONTAINER_STYLE = {
15
- position: 'relative',
16
- } as const satisfies ViewStyle;
17
-
18
- const LABEL_CENTER_STYLE = {
19
- fontWeight: '600',
20
- left: 0,
21
- position: 'absolute',
22
- textAlign: 'center',
23
- top: 0,
24
- } as const satisfies TextStyle;
14
+ import { styles } from './styles';
25
15
 
26
16
  export function CircularProgress({
27
17
  value,
@@ -36,6 +26,7 @@ export function CircularProgress({
36
26
  testID,
37
27
  }: CircularProgressProps): React.JSX.Element {
38
28
  const colors = useColors();
29
+ const fontScale = useFontScale();
39
30
  const normalized = normalizeCircularProgress({ value, size, thickness });
40
31
  const {
41
32
  circumference,
@@ -58,14 +49,20 @@ export function CircularProgress({
58
49
  now: percentage,
59
50
  text: `${percentage}%`,
60
51
  }}
61
- style={[{ height: safeSize, width: safeSize }, style, OUTER_CENTER_STYLE]}
52
+ style={[
53
+ showLabel
54
+ ? [styles.contentSize, { minHeight: safeSize, minWidth: safeSize }]
55
+ : { height: safeSize, width: safeSize },
56
+ style,
57
+ styles.center,
58
+ ]}
62
59
  testID={testID}
63
60
  >
64
61
  <View
65
- style={[{ height: safeSize, width: safeSize }, VISUAL_CONTAINER_STYLE]}
62
+ style={[{ minHeight: safeSize, minWidth: safeSize }, styles.center]}
66
63
  {...A11Y_HIDDEN_PROPS}
67
64
  >
68
- <Svg height={safeSize} width={safeSize}>
65
+ <Svg height={safeSize} width={safeSize} style={styles.ring}>
69
66
  <Circle
70
67
  cx={center}
71
68
  cy={center}
@@ -94,12 +91,9 @@ export function CircularProgress({
94
91
  style={[
95
92
  {
96
93
  color: labelColor ?? colors.foreground,
97
- fontSize: type.nano,
98
- height: safeSize,
99
- lineHeight: safeSize,
100
- width: safeSize,
94
+ fontSize: scaleFontMetric(type.nano, fontScale),
101
95
  },
102
- LABEL_CENTER_STYLE,
96
+ styles.label,
103
97
  ]}
104
98
  >
105
99
  {`${percentage}%`}
@@ -1,29 +1,21 @@
1
+ import type {
2
+ CircularProgressInput,
3
+ NormalizedCircularProgress,
4
+ } from './types';
1
5
  import { createLogger } from '../../../utils/logger';
2
6
 
3
7
  const log = createLogger('CircularProgress');
4
8
  const warnedKeys = new Set<string>();
5
9
 
6
- export type NormalizedCircularProgress = Readonly<{
7
- safeValue: number;
8
- percentage: number;
9
- safeSize: number;
10
- safeThickness: number;
11
- radius: number;
12
- circumference: number;
13
- dashOffset: number;
14
- }>;
15
-
16
10
  function warnOnce(key: string, message: string): void {
17
11
  if (warnedKeys.has(key)) return;
18
12
  warnedKeys.add(key);
19
13
  log.warn(message);
20
14
  }
21
15
 
22
- export function normalizeCircularProgress(input: {
23
- value: number;
24
- size: number;
25
- thickness: number;
26
- }): NormalizedCircularProgress {
16
+ export function normalizeCircularProgress(
17
+ input: CircularProgressInput
18
+ ): NormalizedCircularProgress {
27
19
  const { value, size, thickness } = input;
28
20
 
29
21
  if (!Number.isFinite(value) || value < 0 || value > 1) {
@@ -0,0 +1,13 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export const styles = StyleSheet.create({
4
+ center: { alignItems: 'center', justifyContent: 'center' },
5
+ // 固有尺寸避免父级 stretch 拉宽圆环,文字按自然尺寸占位。
6
+ contentSize: {
7
+ width: 'max-content',
8
+ height: 'max-content',
9
+ },
10
+ // 环不参与文字测量,保持显式直径;文字自然撑开最小容器。
11
+ ring: { position: 'absolute' },
12
+ label: { fontWeight: '600', textAlign: 'center', flexShrink: 0 },
13
+ });
@@ -1,6 +1,6 @@
1
1
  import type { StyleProp, ViewStyle } from 'react-native';
2
2
 
3
- export type CircularProgressProps = {
3
+ export interface CircularProgressProps {
4
4
  /** 当前进度,使用 0..1;越界值会收敛到边界,非有限值按 0 处理。 */
5
5
  value: number;
6
6
  /** 圆环直径,默认 32,最小 16。 */
@@ -21,4 +21,21 @@ export type CircularProgressProps = {
21
21
  style?: StyleProp<ViewStyle>;
22
22
  /** E2E / 测试定位。 */
23
23
  testID?: string;
24
- };
24
+ }
25
+
26
+ /** 内部计算参数,不进入公共 barrel。 */
27
+ export interface CircularProgressInput {
28
+ value: number;
29
+ size: number;
30
+ thickness: number;
31
+ }
32
+
33
+ export interface NormalizedCircularProgress {
34
+ safeValue: number;
35
+ percentage: number;
36
+ safeSize: number;
37
+ safeThickness: number;
38
+ radius: number;
39
+ circumference: number;
40
+ dashOffset: number;
41
+ }
@@ -1,9 +1,13 @@
1
1
  import React from 'react';
2
2
  import Animated from 'react-native-reanimated';
3
3
  import { r, useColors } from '../../../theme';
4
- import { DOT_DEFAULTS, usePulseWithDefaults } from './usePulse';
4
+ import { createLogger } from '../../../utils/logger';
5
+ import { usePulseAnimation } from '../shared/pulse/usePulseAnimation';
6
+ import { PULSE_DOT_DEFAULTS } from './constants';
5
7
  import type { PulseDotProps } from './types';
6
8
 
9
+ const log = createLogger('PulseDot');
10
+
7
11
  export function PulseDot({
8
12
  size = r(6),
9
13
  color,
@@ -13,10 +17,7 @@ export function PulseDot({
13
17
  }: PulseDotProps = {}): React.JSX.Element {
14
18
  const c = useColors();
15
19
  const fill = color ?? c.primary;
16
- // [L-93] 圆点的 from 默认 0.5(比 <Pulse> 的 0.6 更淡)。默认值交给共享的
17
- // DOT_DEFAULTS,不再在解构里写 `from = 0.5` —— 那样 from 会先被默认值填满,
18
- // 归一化层再也分不清「调用方没传」和「调用方传了 0.5」。
19
- const animatedStyle = usePulseWithDefaults(opts, DOT_DEFAULTS, 'PulseDot');
20
+ const animatedStyle = usePulseAnimation(opts, PULSE_DOT_DEFAULTS, log);
20
21
  return (
21
22
  <Animated.View
22
23
  style={[