@unif/react-native-design 0.33.0 → 0.34.0

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 (188) hide show
  1. package/lib/module/components/ui/ActionMenuContent/ActionMenuContent.js +97 -0
  2. package/lib/module/components/ui/ActionMenuContent/ActionMenuContent.js.map +1 -0
  3. package/lib/module/components/ui/ActionMenuContent/index.js +4 -0
  4. package/lib/module/components/ui/ActionMenuContent/index.js.map +1 -0
  5. package/lib/module/components/ui/ActionMenuContent/styles.js +54 -0
  6. package/lib/module/components/ui/ActionMenuContent/styles.js.map +1 -0
  7. package/lib/module/components/ui/ActionMenuContent/types.js.map +1 -0
  8. package/lib/module/components/ui/Avatar/Avatar.js +3 -3
  9. package/lib/module/components/ui/Avatar/Avatar.js.map +1 -1
  10. package/lib/module/components/ui/Button/ButtonBase.js +10 -2
  11. package/lib/module/components/ui/Button/ButtonBase.js.map +1 -1
  12. package/lib/module/components/ui/DrawerHeader/DrawerHeader.js +3 -3
  13. package/lib/module/components/ui/DrawerHeader/DrawerHeader.js.map +1 -1
  14. package/lib/module/components/ui/IconButton/IconButton.js +5 -1
  15. package/lib/module/components/ui/IconButton/IconButton.js.map +1 -1
  16. package/lib/module/components/ui/ImagePreview/ImagePreview.js +200 -0
  17. package/lib/module/components/ui/ImagePreview/ImagePreview.js.map +1 -0
  18. package/lib/module/components/ui/ImagePreview/constants.js +5 -0
  19. package/lib/module/components/ui/ImagePreview/constants.js.map +1 -0
  20. package/lib/module/components/ui/ImagePreview/index.js +4 -0
  21. package/lib/module/components/ui/ImagePreview/index.js.map +1 -0
  22. package/lib/module/components/ui/ImagePreview/styles.js +55 -0
  23. package/lib/module/components/ui/ImagePreview/styles.js.map +1 -0
  24. package/lib/module/components/ui/ImagePreview/types.js +4 -0
  25. package/lib/module/components/ui/ImagePreview/types.js.map +1 -0
  26. package/lib/module/components/ui/Sheet/Sheet.js +40 -0
  27. package/lib/module/components/ui/Sheet/Sheet.js.map +1 -0
  28. package/lib/module/components/ui/Sheet/index.js +4 -0
  29. package/lib/module/components/ui/Sheet/index.js.map +1 -0
  30. package/lib/module/components/ui/Sheet/styles.js +41 -0
  31. package/lib/module/components/ui/Sheet/styles.js.map +1 -0
  32. package/lib/module/components/ui/Sheet/types.js +4 -0
  33. package/lib/module/components/ui/Sheet/types.js.map +1 -0
  34. package/lib/module/components/ui/SmsField/SmsField.js +40 -0
  35. package/lib/module/components/ui/SmsField/SmsField.js.map +1 -0
  36. package/lib/module/components/ui/SmsField/index.js +4 -0
  37. package/lib/module/components/ui/SmsField/index.js.map +1 -0
  38. package/lib/module/components/ui/SmsField/types.js +4 -0
  39. package/lib/module/components/ui/SmsField/types.js.map +1 -0
  40. package/lib/module/components/ui/TextEntryContent/TextEntryContent.js +60 -0
  41. package/lib/module/components/ui/TextEntryContent/TextEntryContent.js.map +1 -0
  42. package/lib/module/components/ui/TextEntryContent/index.js +4 -0
  43. package/lib/module/components/ui/TextEntryContent/index.js.map +1 -0
  44. package/lib/module/components/ui/TextEntryContent/styles.js +29 -0
  45. package/lib/module/components/ui/TextEntryContent/styles.js.map +1 -0
  46. package/lib/module/components/ui/TextEntryContent/types.js +4 -0
  47. package/lib/module/components/ui/TextEntryContent/types.js.map +1 -0
  48. package/lib/module/components/ui/Thumbnail/Thumbnail.js +3 -3
  49. package/lib/module/components/ui/Thumbnail/Thumbnail.js.map +1 -1
  50. package/lib/module/components/ui/index.js +5 -1
  51. package/lib/module/components/ui/index.js.map +1 -1
  52. package/lib/module/components/ui/shared/ImageAttempt.js.map +1 -1
  53. package/lib/module/components/ui/shared/selectImageAttemptSource.shared.js +6 -5
  54. package/lib/module/components/ui/shared/selectImageAttemptSource.shared.js.map +1 -1
  55. package/lib/module/components/ui/shared/useImageSource.js +11 -0
  56. package/lib/module/components/ui/shared/useImageSource.js.map +1 -0
  57. package/lib/module/icons/data.js +87 -1
  58. package/lib/module/icons/data.js.map +1 -1
  59. package/lib/module/utils/imageSource.js +47 -13
  60. package/lib/module/utils/imageSource.js.map +1 -1
  61. package/lib/typescript/src/components/ui/ActionMenuContent/ActionMenuContent.d.ts +4 -0
  62. package/lib/typescript/src/components/ui/ActionMenuContent/ActionMenuContent.d.ts.map +1 -0
  63. package/lib/typescript/src/components/ui/ActionMenuContent/index.d.ts +3 -0
  64. package/lib/typescript/src/components/ui/ActionMenuContent/index.d.ts.map +1 -0
  65. package/lib/typescript/src/components/ui/ActionMenuContent/styles.d.ts +51 -0
  66. package/lib/typescript/src/components/ui/ActionMenuContent/styles.d.ts.map +1 -0
  67. package/lib/typescript/src/components/ui/ActionMenuContent/types.d.ts +25 -0
  68. package/lib/typescript/src/components/ui/ActionMenuContent/types.d.ts.map +1 -0
  69. package/lib/typescript/src/components/ui/Button/ButtonBase.d.ts +3 -1
  70. package/lib/typescript/src/components/ui/Button/ButtonBase.d.ts.map +1 -1
  71. package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts +1 -1
  72. package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts.map +1 -1
  73. package/lib/typescript/src/components/ui/IconButton/types.d.ts +4 -0
  74. package/lib/typescript/src/components/ui/IconButton/types.d.ts.map +1 -1
  75. package/lib/typescript/src/components/ui/ImagePreview/ImagePreview.d.ts +3 -0
  76. package/lib/typescript/src/components/ui/ImagePreview/ImagePreview.d.ts.map +1 -0
  77. package/lib/typescript/src/components/ui/ImagePreview/constants.d.ts +3 -0
  78. package/lib/typescript/src/components/ui/ImagePreview/constants.d.ts.map +1 -0
  79. package/lib/typescript/src/components/ui/ImagePreview/index.d.ts +3 -0
  80. package/lib/typescript/src/components/ui/ImagePreview/index.d.ts.map +1 -0
  81. package/lib/typescript/src/components/ui/ImagePreview/styles.d.ts +56 -0
  82. package/lib/typescript/src/components/ui/ImagePreview/styles.d.ts.map +1 -0
  83. package/lib/typescript/src/components/ui/ImagePreview/types.d.ts +33 -0
  84. package/lib/typescript/src/components/ui/ImagePreview/types.d.ts.map +1 -0
  85. package/lib/typescript/src/components/ui/Sheet/Sheet.d.ts +4 -0
  86. package/lib/typescript/src/components/ui/Sheet/Sheet.d.ts.map +1 -0
  87. package/lib/typescript/src/components/ui/Sheet/index.d.ts +3 -0
  88. package/lib/typescript/src/components/ui/Sheet/index.d.ts.map +1 -0
  89. package/lib/typescript/src/components/ui/Sheet/styles.d.ts +38 -0
  90. package/lib/typescript/src/components/ui/Sheet/styles.d.ts.map +1 -0
  91. package/lib/typescript/src/components/ui/Sheet/types.d.ts +13 -0
  92. package/lib/typescript/src/components/ui/Sheet/types.d.ts.map +1 -0
  93. package/lib/typescript/src/components/ui/SmsField/SmsField.d.ts +4 -0
  94. package/lib/typescript/src/components/ui/SmsField/SmsField.d.ts.map +1 -0
  95. package/lib/typescript/src/components/ui/SmsField/index.d.ts +3 -0
  96. package/lib/typescript/src/components/ui/SmsField/index.d.ts.map +1 -0
  97. package/lib/typescript/src/components/ui/SmsField/types.d.ts +12 -0
  98. package/lib/typescript/src/components/ui/SmsField/types.d.ts.map +1 -0
  99. package/lib/typescript/src/components/ui/TextEntryContent/TextEntryContent.d.ts +4 -0
  100. package/lib/typescript/src/components/ui/TextEntryContent/TextEntryContent.d.ts.map +1 -0
  101. package/lib/typescript/src/components/ui/TextEntryContent/index.d.ts +3 -0
  102. package/lib/typescript/src/components/ui/TextEntryContent/index.d.ts.map +1 -0
  103. package/lib/typescript/src/components/ui/TextEntryContent/styles.d.ts +26 -0
  104. package/lib/typescript/src/components/ui/TextEntryContent/styles.d.ts.map +1 -0
  105. package/lib/typescript/src/components/ui/TextEntryContent/types.d.ts +18 -0
  106. package/lib/typescript/src/components/ui/TextEntryContent/types.d.ts.map +1 -0
  107. package/lib/typescript/src/components/ui/index.d.ts +10 -2
  108. package/lib/typescript/src/components/ui/index.d.ts.map +1 -1
  109. package/lib/typescript/src/components/ui/shared/ImageAttempt.d.ts +3 -2
  110. package/lib/typescript/src/components/ui/shared/ImageAttempt.d.ts.map +1 -1
  111. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.shared.d.ts +3 -2
  112. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.shared.d.ts.map +1 -1
  113. package/lib/typescript/src/components/ui/shared/useImageSource.d.ts +6 -0
  114. package/lib/typescript/src/components/ui/shared/useImageSource.d.ts.map +1 -0
  115. package/lib/typescript/src/icons/data.d.ts +1 -1
  116. package/lib/typescript/src/icons/data.d.ts.map +1 -1
  117. package/lib/typescript/src/utils/imageSource.d.ts +3 -2
  118. package/lib/typescript/src/utils/imageSource.d.ts.map +1 -1
  119. package/lib/typescript/type-tests/content-api.d.ts +2 -0
  120. package/lib/typescript/type-tests/content-api.d.ts.map +1 -0
  121. package/package.json +1 -1
  122. package/src/components/ui/ActionMenuContent/ActionMenuContent.tsx +118 -0
  123. package/src/components/ui/ActionMenuContent/index.ts +6 -0
  124. package/src/components/ui/ActionMenuContent/styles.ts +47 -0
  125. package/src/components/ui/ActionMenuContent/types.ts +27 -0
  126. package/src/components/ui/Avatar/Avatar.tsx +3 -3
  127. package/src/components/ui/Button/ButtonBase.tsx +11 -2
  128. package/src/components/ui/DrawerHeader/DrawerHeader.tsx +3 -3
  129. package/src/components/ui/IconButton/IconButton.tsx +9 -1
  130. package/src/components/ui/IconButton/types.ts +4 -0
  131. package/src/components/ui/ImagePreview/ImagePreview.tsx +243 -0
  132. package/src/components/ui/ImagePreview/constants.ts +2 -0
  133. package/src/components/ui/ImagePreview/index.ts +6 -0
  134. package/src/components/ui/ImagePreview/styles.ts +48 -0
  135. package/src/components/ui/ImagePreview/types.ts +37 -0
  136. package/src/components/ui/Sheet/Sheet.tsx +43 -0
  137. package/src/components/ui/Sheet/index.ts +2 -0
  138. package/src/components/ui/Sheet/styles.ts +40 -0
  139. package/src/components/ui/Sheet/types.ts +14 -0
  140. package/src/components/ui/SmsField/SmsField.tsx +40 -0
  141. package/src/components/ui/SmsField/index.ts +2 -0
  142. package/src/components/ui/SmsField/types.ts +15 -0
  143. package/src/components/ui/TextEntryContent/TextEntryContent.tsx +56 -0
  144. package/src/components/ui/TextEntryContent/index.ts +2 -0
  145. package/src/components/ui/TextEntryContent/styles.ts +17 -0
  146. package/src/components/ui/TextEntryContent/types.ts +18 -0
  147. package/src/components/ui/Thumbnail/Thumbnail.tsx +3 -3
  148. package/src/components/ui/index.ts +18 -2
  149. package/src/components/ui/shared/ImageAttempt.tsx +3 -2
  150. package/src/components/ui/shared/selectImageAttemptSource.shared.ts +7 -5
  151. package/src/components/ui/shared/useImageSource.ts +8 -0
  152. package/src/icons/data.ts +134 -0
  153. package/src/utils/imageSource.ts +78 -15
  154. package/lib/module/components/ui/BorderBeam/BorderBeam.js +0 -102
  155. package/lib/module/components/ui/BorderBeam/BorderBeam.js.map +0 -1
  156. package/lib/module/components/ui/BorderBeam/BorderBeam.web.js +0 -108
  157. package/lib/module/components/ui/BorderBeam/BorderBeam.web.js.map +0 -1
  158. package/lib/module/components/ui/BorderBeam/index.js +0 -4
  159. package/lib/module/components/ui/BorderBeam/index.js.map +0 -1
  160. package/lib/module/components/ui/BorderBeam/normalizeBorderBeam.js +0 -23
  161. package/lib/module/components/ui/BorderBeam/normalizeBorderBeam.js.map +0 -1
  162. package/lib/module/components/ui/BorderBeam/shared.js +0 -54
  163. package/lib/module/components/ui/BorderBeam/shared.js.map +0 -1
  164. package/lib/module/components/ui/BorderBeam/styles.js +0 -18
  165. package/lib/module/components/ui/BorderBeam/styles.js.map +0 -1
  166. package/lib/module/components/ui/BorderBeam/types.js.map +0 -1
  167. package/lib/typescript/src/components/ui/BorderBeam/BorderBeam.d.ts +0 -10
  168. package/lib/typescript/src/components/ui/BorderBeam/BorderBeam.d.ts.map +0 -1
  169. package/lib/typescript/src/components/ui/BorderBeam/BorderBeam.web.d.ts +0 -5
  170. package/lib/typescript/src/components/ui/BorderBeam/BorderBeam.web.d.ts.map +0 -1
  171. package/lib/typescript/src/components/ui/BorderBeam/index.d.ts +0 -3
  172. package/lib/typescript/src/components/ui/BorderBeam/index.d.ts.map +0 -1
  173. package/lib/typescript/src/components/ui/BorderBeam/normalizeBorderBeam.d.ts +0 -16
  174. package/lib/typescript/src/components/ui/BorderBeam/normalizeBorderBeam.d.ts.map +0 -1
  175. package/lib/typescript/src/components/ui/BorderBeam/shared.d.ts +0 -28
  176. package/lib/typescript/src/components/ui/BorderBeam/shared.d.ts.map +0 -1
  177. package/lib/typescript/src/components/ui/BorderBeam/styles.d.ts +0 -15
  178. package/lib/typescript/src/components/ui/BorderBeam/styles.d.ts.map +0 -1
  179. package/lib/typescript/src/components/ui/BorderBeam/types.d.ts +0 -23
  180. package/lib/typescript/src/components/ui/BorderBeam/types.d.ts.map +0 -1
  181. package/src/components/ui/BorderBeam/BorderBeam.tsx +0 -130
  182. package/src/components/ui/BorderBeam/BorderBeam.web.tsx +0 -127
  183. package/src/components/ui/BorderBeam/index.ts +0 -2
  184. package/src/components/ui/BorderBeam/normalizeBorderBeam.ts +0 -58
  185. package/src/components/ui/BorderBeam/shared.ts +0 -47
  186. package/src/components/ui/BorderBeam/styles.ts +0 -16
  187. package/src/components/ui/BorderBeam/types.ts +0 -23
  188. /package/lib/module/components/ui/{BorderBeam → ActionMenuContent}/types.js +0 -0
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import { ScrollView, View } from 'react-native';
3
+ import { useThemedStyles } from '../../../theme';
4
+ import { makeStyles } from './styles';
5
+ import type { SheetProps } from './types';
6
+
7
+ export function Sheet({
8
+ children,
9
+ header,
10
+ footer,
11
+ contentMode = 'fixed',
12
+ contentContainerStyle,
13
+ style,
14
+ testID,
15
+ }: SheetProps): React.JSX.Element {
16
+ const styles = useThemedStyles(makeStyles);
17
+
18
+ return (
19
+ <View style={[styles.root, style]} testID={testID}>
20
+ {header ?? (
21
+ <View style={styles.grabberContainer}>
22
+ <View style={styles.grabber} />
23
+ </View>
24
+ )}
25
+ {contentMode === 'scroll' ? (
26
+ <ScrollView
27
+ style={styles.contentRegion}
28
+ contentContainerStyle={[styles.content, contentContainerStyle]}
29
+ keyboardShouldPersistTaps="handled"
30
+ >
31
+ {children}
32
+ </ScrollView>
33
+ ) : (
34
+ <View
35
+ style={[styles.contentRegion, styles.content, contentContainerStyle]}
36
+ >
37
+ {children}
38
+ </View>
39
+ )}
40
+ {footer ? <View style={styles.footer}>{footer}</View> : null}
41
+ </View>
42
+ );
43
+ }
@@ -0,0 +1,2 @@
1
+ export { Sheet } from './Sheet';
2
+ export type { SheetContentMode, SheetProps } from './types';
@@ -0,0 +1,40 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { space, type ColorTokens } from '../../../theme';
3
+
4
+ export const makeStyles = (colors: ColorTokens) =>
5
+ StyleSheet.create({
6
+ root: {
7
+ flex: 1,
8
+ minHeight: 0,
9
+ backgroundColor: colors.surface,
10
+ },
11
+ grabberContainer: {
12
+ alignItems: 'center',
13
+ paddingTop: space['3'],
14
+ paddingBottom: space['2'],
15
+ },
16
+ grabber: {
17
+ width: 36,
18
+ height: 5,
19
+ borderRadius: 3,
20
+ backgroundColor: colors.foregroundMuted,
21
+ },
22
+ contentRegion: {
23
+ flex: 1,
24
+ minHeight: 0,
25
+ },
26
+ content: {
27
+ paddingHorizontal: space['9'],
28
+ paddingTop: space['4'],
29
+ paddingBottom: space['9'],
30
+ gap: space['5'],
31
+ },
32
+ footer: {
33
+ backgroundColor: colors.surface,
34
+ paddingHorizontal: space['9'],
35
+ paddingTop: space['5'],
36
+ paddingBottom: space['6'],
37
+ borderTopWidth: StyleSheet.hairlineWidth,
38
+ borderTopColor: colors.outline,
39
+ },
40
+ });
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { StyleProp, ViewStyle } from 'react-native';
3
+
4
+ export type SheetContentMode = 'fixed' | 'scroll' | 'external-scroll';
5
+
6
+ export interface SheetProps {
7
+ children: ReactNode;
8
+ header?: ReactNode;
9
+ footer?: ReactNode;
10
+ contentMode?: SheetContentMode;
11
+ contentContainerStyle?: StyleProp<ViewStyle>;
12
+ style?: StyleProp<ViewStyle>;
13
+ testID?: string;
14
+ }
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { useColors } from '../../../theme';
3
+ import { Input } from '../Input';
4
+ import type { SmsFieldProps } from './types';
5
+
6
+ export function SmsField({
7
+ value,
8
+ onChangeText,
9
+ remainingSeconds,
10
+ sendDisabled,
11
+ onSend,
12
+ sendLabel,
13
+ sendAccessibilityLabel,
14
+ ...inputProps
15
+ }: SmsFieldProps): React.JSX.Element {
16
+ const colors = useColors();
17
+ return (
18
+ <Input
19
+ {...inputProps}
20
+ value={value}
21
+ onChangeText={onChangeText}
22
+ keyboardType="number-pad"
23
+ autoComplete="sms-otp"
24
+ textContentType="oneTimeCode"
25
+ leading={{
26
+ kind: 'icon',
27
+ icon: 'mail',
28
+ size: 18,
29
+ color: colors.iconFaint40,
30
+ }}
31
+ trailing={{
32
+ kind: 'action',
33
+ label: sendLabel,
34
+ accessibilityLabel: sendAccessibilityLabel ?? sendLabel,
35
+ disabled: sendDisabled || remainingSeconds > 0,
36
+ onPress: onSend,
37
+ }}
38
+ />
39
+ );
40
+ }
@@ -0,0 +1,2 @@
1
+ export { SmsField } from './SmsField';
2
+ export type { SmsFieldProps } from './types';
@@ -0,0 +1,15 @@
1
+ import type { InputProps } from '../Input';
2
+
3
+ /** 长度、提示及发送文案由调用方提供;remainingSeconds 只控制冷却禁用。 */
4
+ export interface SmsFieldProps extends Pick<
5
+ InputProps,
6
+ 'maxLength' | 'placeholder' | 'editable' | 'accessibilityLabel' | 'testID'
7
+ > {
8
+ value: string;
9
+ onChangeText(value: string): void;
10
+ remainingSeconds: number;
11
+ sendLabel: string;
12
+ sendAccessibilityLabel?: string;
13
+ sendDisabled?: boolean;
14
+ onSend(): void;
15
+ }
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { Text, View } from 'react-native';
3
+ import { useThemedStyles } from '../../../theme';
4
+ import { Button } from '../Button';
5
+ import { Textarea } from '../Textarea';
6
+ import { makeStyles } from './styles';
7
+ import type { TextEntryContentProps } from './types';
8
+
9
+ export function TextEntryContent({
10
+ title,
11
+ value,
12
+ onChangeText,
13
+ onSubmit,
14
+ onCancel,
15
+ message,
16
+ busy = false,
17
+ maxLength,
18
+ confirmLabel = '确认',
19
+ cancelLabel = '取消',
20
+ autoFocus = true,
21
+ style,
22
+ testID,
23
+ }: TextEntryContentProps): React.JSX.Element {
24
+ const styles = useThemedStyles(makeStyles);
25
+ return (
26
+ <View style={[styles.root, style]} testID={testID}>
27
+ <Text style={styles.title} accessibilityRole="header">
28
+ {title}
29
+ </Text>
30
+ {message ? <Text style={styles.message}>{message}</Text> : null}
31
+ <Textarea
32
+ value={value}
33
+ onChangeText={onChangeText}
34
+ maxLength={maxLength}
35
+ editable={!busy}
36
+ autoFocus={autoFocus}
37
+ accessibilityLabel={title}
38
+ />
39
+ <View style={styles.actions}>
40
+ <Button
41
+ label={confirmLabel}
42
+ size="sm"
43
+ loading={busy}
44
+ onPress={() => onSubmit(value)}
45
+ />
46
+ <Button
47
+ label={cancelLabel}
48
+ size="sm"
49
+ variant="outline"
50
+ disabled={busy}
51
+ onPress={onCancel}
52
+ />
53
+ </View>
54
+ </View>
55
+ );
56
+ }
@@ -0,0 +1,2 @@
1
+ export { TextEntryContent } from './TextEntryContent';
2
+ export type { TextEntryContentProps } from './types';
@@ -0,0 +1,17 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { fw, radius, space, type, type ColorTokens } from '../../../theme';
3
+
4
+ export const makeStyles = (colors: ColorTokens) =>
5
+ StyleSheet.create({
6
+ root: {
7
+ gap: space[4],
8
+ padding: space[5],
9
+ borderWidth: 1,
10
+ borderColor: colors.outline,
11
+ borderRadius: radius.xl,
12
+ backgroundColor: colors.surface,
13
+ },
14
+ title: { color: colors.foreground, fontSize: type.h3, fontWeight: fw.semi },
15
+ message: { color: colors.foregroundMuted, fontSize: type.sm },
16
+ actions: { flexDirection: 'row', flexWrap: 'wrap', gap: space[3] },
17
+ });
@@ -0,0 +1,18 @@
1
+ import type { StyleProp, ViewStyle } from 'react-native';
2
+
3
+ /** 受控文字编辑内容;弹层、键盘和业务提交结果由宿主负责。 */
4
+ export interface TextEntryContentProps {
5
+ title: string;
6
+ value: string;
7
+ onChangeText(value: string): void;
8
+ onSubmit(value: string): void;
9
+ onCancel(): void;
10
+ message?: string;
11
+ busy?: boolean;
12
+ maxLength?: number;
13
+ confirmLabel?: string;
14
+ cancelLabel?: string;
15
+ autoFocus?: boolean;
16
+ style?: StyleProp<ViewStyle>;
17
+ testID?: string;
18
+ }
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
3
  import { useColors, useThemedStyles } from '../../../theme';
4
- import { resolveImageSource } from '../../../utils/imageSource';
4
+ import { useImageSource } from '../shared/useImageSource';
5
5
  import { createLogger } from '../../../utils/logger';
6
6
  import { ImageAttempt } from '../shared/ImageAttempt';
7
7
  import { A11Y_HIDDEN_PROPS } from '../shared/a11y';
@@ -45,7 +45,7 @@ export function Thumbnail(props: ThumbnailProps): React.JSX.Element {
45
45
  ? { uri: uri.trim() }
46
46
  : source
47
47
  : undefined;
48
- const resolvedSource = resolveImageSource(sourceCandidate);
48
+ const resolvedSource = useImageSource(sourceCandidate);
49
49
  const sanitizedImageStyle = sanitizeThumbnailImageStyle(imageStyle);
50
50
  const diagnostics = [
51
51
  ...normalizedDimensions.diagnostics,
@@ -94,7 +94,7 @@ export function Thumbnail(props: ThumbnailProps): React.JSX.Element {
94
94
  <ImageAttempt
95
95
  {...imageAccessibilityProps}
96
96
  key={resolvedSource.key}
97
- source={resolvedSource.source}
97
+ source={resolvedSource}
98
98
  fallback={fallbackContent}
99
99
  style={[sanitizedImageStyle.style, StyleSheet.absoluteFill]}
100
100
  resizeMode={resizeMode}
@@ -9,8 +9,6 @@ export { AvatarGroup } from './AvatarGroup';
9
9
  export type { AvatarGroupItem, AvatarGroupProps } from './AvatarGroup';
10
10
  export { BlurLayer } from './BlurLayer';
11
11
  export type { BlurLayerProps } from './BlurLayer';
12
- export { BorderBeam } from './BorderBeam';
13
- export type { BorderBeamProps } from './BorderBeam';
14
12
  export { Button } from './Button';
15
13
  export type { ButtonProps, ButtonSize, ButtonVariant } from './Button';
16
14
  export { Card } from './Card';
@@ -109,3 +107,21 @@ export type {
109
107
  ToastKind,
110
108
  ToastPosition,
111
109
  } from './Toast';
110
+ export { ActionMenuContent } from './ActionMenuContent';
111
+ export type {
112
+ ActionMenuAction,
113
+ ActionMenuConfirmation,
114
+ ActionMenuContentProps,
115
+ } from './ActionMenuContent';
116
+ export { ImagePreview } from './ImagePreview';
117
+ export type {
118
+ ImagePreviewItem,
119
+ ImagePreviewProps,
120
+ ImagePreviewHandle,
121
+ } from './ImagePreview';
122
+ export { Sheet } from './Sheet';
123
+ export type { SheetContentMode, SheetProps } from './Sheet';
124
+ export { SmsField } from './SmsField';
125
+ export type { SmsFieldProps } from './SmsField';
126
+ export { TextEntryContent } from './TextEntryContent';
127
+ export type { TextEntryContentProps } from './TextEntryContent';
@@ -1,10 +1,11 @@
1
1
  import React, { useCallback, useState } from 'react';
2
2
  import { Image } from 'react-native';
3
- import type { ImageProps, ImageSourcePropType } from 'react-native';
3
+ import type { ImageProps } from 'react-native';
4
+ import type { ResolvedImageSource } from '../../../utils/imageSource';
4
5
  import { selectImageAttemptSource } from './selectImageAttemptSource';
5
6
 
6
7
  type ImageAttemptProps = Omit<ImageProps, 'onError' | 'source'> & {
7
- source: ImageSourcePropType;
8
+ source: ResolvedImageSource;
8
9
  fallback: React.ReactNode;
9
10
  };
10
11
 
@@ -1,16 +1,18 @@
1
1
  import type { ImageSourcePropType } from 'react-native';
2
- import { isValidImageSource } from '../../../utils/imageSource';
2
+ import type { ResolvedImageSource } from '../../../utils/imageSource';
3
3
 
4
+ // Input validation belongs to the media component's resolver. Its frozen result
5
+ // is safe to select here without reading or serializing the original input again.
4
6
  export function selectNativeImageAttemptSource(
5
- source: unknown
7
+ resolved: ResolvedImageSource | undefined
6
8
  ): ImageSourcePropType | undefined {
7
- return isValidImageSource(source) ? source : undefined;
9
+ return resolved?.source;
8
10
  }
9
11
 
10
12
  export function selectWebImageAttemptSource(
11
- source: unknown
13
+ resolved: ResolvedImageSource | undefined
12
14
  ): ImageSourcePropType | undefined {
13
- if (!isValidImageSource(source)) return undefined;
15
+ const source = resolved?.source;
14
16
 
15
17
  // RNW 0.21 不解析 native 的 candidate 数组;Web 明确使用第一候选项。
16
18
  return Array.isArray(source) ? source[0] : source;
@@ -0,0 +1,8 @@
1
+ import { useMemo } from 'react';
2
+ import { createImageSourceResolver } from '../../../utils/imageSource';
3
+
4
+ /** Reuse immutable image inputs without retaining a global source cache. */
5
+ export function useImageSource(source: unknown) {
6
+ const resolve = useMemo(createImageSourceResolver, []);
7
+ return resolve(source);
8
+ }
package/src/icons/data.ts CHANGED
@@ -15,6 +15,8 @@ export type IconName =
15
15
  | 'aspect-4-3'
16
16
  | 'attachment'
17
17
  | 'bag-check'
18
+ | 'bank'
19
+ | 'bed'
18
20
  | 'bell'
19
21
  | 'bluetooth'
20
22
  | 'bot'
@@ -41,8 +43,10 @@ export type IconName =
41
43
  | 'clipboard-user'
42
44
  | 'clipboard'
43
45
  | 'close'
46
+ | 'coffee'
44
47
  | 'coin'
45
48
  | 'copy'
49
+ | 'crosshair'
46
50
  | 'dashboard-megaphone'
47
51
  | 'dashboard-star'
48
52
  | 'download'
@@ -58,6 +62,7 @@ export type IconName =
58
62
  | 'flash-auto'
59
63
  | 'flash-off'
60
64
  | 'flash-on'
65
+ | 'fuel'
61
66
  | 'grid'
62
67
  | 'hand'
63
68
  | 'heart'
@@ -73,12 +78,15 @@ export type IconName =
73
78
  | 'logout'
74
79
  | 'mail'
75
80
  | 'maximize'
81
+ | 'medical-cross'
76
82
  | 'menu'
77
83
  | 'mic-on'
78
84
  | 'mic'
79
85
  | 'minimize'
86
+ | 'minus'
80
87
  | 'more-h'
81
88
  | 'more-v'
89
+ | 'navigation-pointer'
82
90
  | 'order'
83
91
  | 'package'
84
92
  | 'paperclip'
@@ -100,6 +108,7 @@ export type IconName =
100
108
  | 'share'
101
109
  | 'shelf-pay'
102
110
  | 'shield-check'
111
+ | 'shopping-bag'
103
112
  | 'shutter-recording'
104
113
  | 'shutter'
105
114
  | 'sidebar'
@@ -107,8 +116,10 @@ export type IconName =
107
116
  | 'sound-off'
108
117
  | 'sound'
109
118
  | 'spark'
119
+ | 'star-filled'
110
120
  | 'star'
111
121
  | 'stop'
122
+ | 'store'
112
123
  | 'storefront-ai'
113
124
  | 'storefront-arrow'
114
125
  | 'storefront-check'
@@ -122,6 +133,7 @@ export type IconName =
122
133
  | 'upload'
123
134
  | 'user'
124
135
  | 'users-search'
136
+ | 'utensils'
125
137
  | 'visit'
126
138
  | 'warning';
127
139
 
@@ -290,6 +302,24 @@ export const ICONS: Record<IconName, IconDef> = {
290
302
  },
291
303
  ],
292
304
  },
305
+ 'bank': {
306
+ strokeWidth: 1.75,
307
+ elements: [
308
+ {
309
+ kind: 'path',
310
+ d: 'M3 9l9-5 9 5 M5 9v8 M9 9v8 M15 9v8 M19 9v8 M3 21h18 M4 17h16',
311
+ },
312
+ ],
313
+ },
314
+ 'bed': {
315
+ strokeWidth: 1.75,
316
+ elements: [
317
+ {
318
+ kind: 'path',
319
+ d: 'M3 6v12 M3 11h18v7 M21 18v-3 M7 11V9a1 1 0 0 1 1-1h9a3 3 0 0 1 3 3',
320
+ },
321
+ ],
322
+ },
293
323
  'bell': {
294
324
  strokeWidth: 1.75,
295
325
  elements: [
@@ -858,6 +888,15 @@ export const ICONS: Record<IconName, IconDef> = {
858
888
  },
859
889
  ],
860
890
  },
891
+ 'coffee': {
892
+ strokeWidth: 1.75,
893
+ elements: [
894
+ {
895
+ kind: 'path',
896
+ d: 'M4 8h13v5a5 5 0 0 1-5 5H9a5 5 0 0 1-5-5V8z M17 9h2a2 2 0 0 1 0 6h-2 M8 3v2 M12 3v2',
897
+ },
898
+ ],
899
+ },
861
900
  'coin': {
862
901
  strokeWidth: 1.75,
863
902
  elements: [
@@ -902,6 +941,15 @@ export const ICONS: Record<IconName, IconDef> = {
902
941
  },
903
942
  ],
904
943
  },
944
+ 'crosshair': {
945
+ strokeWidth: 1.75,
946
+ elements: [
947
+ {
948
+ kind: 'path',
949
+ d: 'M16 12a4 4 0 1 1-8 0a4 4 0 1 1 8 0 M12 2v3 M12 19v3 M2 12h3 M19 12h3',
950
+ },
951
+ ],
952
+ },
905
953
  'dashboard-megaphone': {
906
954
  strokeWidth: 1.75,
907
955
  elements: [
@@ -1160,6 +1208,15 @@ export const ICONS: Record<IconName, IconDef> = {
1160
1208
  },
1161
1209
  ],
1162
1210
  },
1211
+ 'fuel': {
1212
+ strokeWidth: 1.75,
1213
+ elements: [
1214
+ {
1215
+ kind: 'path',
1216
+ d: 'M5 21V5a2 2 0 0 1 2-2h5a2 2 0 0 1 2 2v16 M4 21h11 M7 9h5 M14 8l3 3v6a2 2 0 0 0 2 2 2 2 0 0 0 2-2v-7l-3-3',
1217
+ },
1218
+ ],
1219
+ },
1163
1220
  'grid': {
1164
1221
  strokeWidth: 1.75,
1165
1222
  elements: [
@@ -1459,6 +1516,15 @@ export const ICONS: Record<IconName, IconDef> = {
1459
1516
  },
1460
1517
  ],
1461
1518
  },
1519
+ 'medical-cross': {
1520
+ strokeWidth: 1.75,
1521
+ elements: [
1522
+ {
1523
+ kind: 'path',
1524
+ d: 'M7 4h10a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3z M12 8v8 M8 12h8',
1525
+ },
1526
+ ],
1527
+ },
1462
1528
  'menu': {
1463
1529
  strokeWidth: 1.75,
1464
1530
  elements: [
@@ -1519,6 +1585,15 @@ export const ICONS: Record<IconName, IconDef> = {
1519
1585
  },
1520
1586
  ],
1521
1587
  },
1588
+ 'minus': {
1589
+ strokeWidth: 1.75,
1590
+ elements: [
1591
+ {
1592
+ kind: 'path',
1593
+ d: 'M5 12h14',
1594
+ },
1595
+ ],
1596
+ },
1522
1597
  'more-h': {
1523
1598
  strokeWidth: 1.75,
1524
1599
  elements: [
@@ -1571,6 +1646,15 @@ export const ICONS: Record<IconName, IconDef> = {
1571
1646
  },
1572
1647
  ],
1573
1648
  },
1649
+ 'navigation-pointer': {
1650
+ strokeWidth: 1.75,
1651
+ elements: [
1652
+ {
1653
+ kind: 'path',
1654
+ d: 'M21 4L3 11l7 2 2 7 9-16z',
1655
+ },
1656
+ ],
1657
+ },
1574
1658
  'order': {
1575
1659
  strokeWidth: 1.75,
1576
1660
  elements: [
@@ -1994,6 +2078,15 @@ export const ICONS: Record<IconName, IconDef> = {
1994
2078
  },
1995
2079
  ],
1996
2080
  },
2081
+ 'shopping-bag': {
2082
+ strokeWidth: 1.75,
2083
+ elements: [
2084
+ {
2085
+ kind: 'path',
2086
+ d: 'M5 8h14l-1 12H6L5 8z M9 8V6a3 3 0 0 1 6 0v2',
2087
+ },
2088
+ ],
2089
+ },
1997
2090
  'shutter-recording': {
1998
2091
  strokeWidth: 1.75,
1999
2092
  elements: [
@@ -2127,6 +2220,17 @@ export const ICONS: Record<IconName, IconDef> = {
2127
2220
  },
2128
2221
  ],
2129
2222
  },
2223
+ 'star-filled': {
2224
+ strokeWidth: 1.75,
2225
+ elements: [
2226
+ {
2227
+ kind: 'path',
2228
+ d: 'M12 3.2l2.5 5.1 5.6.8-4.05 3.95.96 5.6L12 16.9 6.99 18.65l.96-5.6L3.9 9.1l5.6-.8L12 3.2z',
2229
+ fill: 'currentColor',
2230
+ stroke: 'none',
2231
+ },
2232
+ ],
2233
+ },
2130
2234
  'star': {
2131
2235
  strokeWidth: 1.75,
2132
2236
  elements: [
@@ -2151,6 +2255,15 @@ export const ICONS: Record<IconName, IconDef> = {
2151
2255
  },
2152
2256
  ],
2153
2257
  },
2258
+ 'store': {
2259
+ strokeWidth: 1.75,
2260
+ elements: [
2261
+ {
2262
+ kind: 'path',
2263
+ d: 'M4 9l1.2-4h13.6L20 9 M5 9.5V20h14V9.5 M4 9c0 1.4 1 2.3 2.2 2.3S8.4 10.4 8.4 9 M8.4 9c0 1.4 1 2.3 2.2 2.3S12.8 10.4 12.8 9 M12.8 9c0 1.4 1 2.3 2.2 2.3S17.2 10.4 17.2 9 M17.2 9c0 1.4 1 2.3 2.2 2.3 M9.5 20v-5h5v5',
2264
+ },
2265
+ ],
2266
+ },
2154
2267
  'storefront-ai': {
2155
2268
  strokeWidth: 1.75,
2156
2269
  elements: [
@@ -2461,6 +2574,15 @@ export const ICONS: Record<IconName, IconDef> = {
2461
2574
  },
2462
2575
  ],
2463
2576
  },
2577
+ 'utensils': {
2578
+ strokeWidth: 1.75,
2579
+ elements: [
2580
+ {
2581
+ kind: 'path',
2582
+ d: 'M7 3v7 M5 3v4a2 2 0 0 0 2 2 M9 3v4a2 2 0 0 1-2 2 M7 11v10 M16 3c-1.5 0-2.5 2-2.5 5s1 4 2.5 4 M16 3v18',
2583
+ },
2584
+ ],
2585
+ },
2464
2586
  'visit': {
2465
2587
  strokeWidth: 1.75,
2466
2588
  elements: [
@@ -2515,6 +2637,8 @@ export const ICON_NAMES: IconName[] = [
2515
2637
  'aspect-4-3',
2516
2638
  'attachment',
2517
2639
  'bag-check',
2640
+ 'bank',
2641
+ 'bed',
2518
2642
  'bell',
2519
2643
  'bluetooth',
2520
2644
  'bot',
@@ -2541,8 +2665,10 @@ export const ICON_NAMES: IconName[] = [
2541
2665
  'clipboard-user',
2542
2666
  'clipboard',
2543
2667
  'close',
2668
+ 'coffee',
2544
2669
  'coin',
2545
2670
  'copy',
2671
+ 'crosshair',
2546
2672
  'dashboard-megaphone',
2547
2673
  'dashboard-star',
2548
2674
  'download',
@@ -2558,6 +2684,7 @@ export const ICON_NAMES: IconName[] = [
2558
2684
  'flash-auto',
2559
2685
  'flash-off',
2560
2686
  'flash-on',
2687
+ 'fuel',
2561
2688
  'grid',
2562
2689
  'hand',
2563
2690
  'heart',
@@ -2573,12 +2700,15 @@ export const ICON_NAMES: IconName[] = [
2573
2700
  'logout',
2574
2701
  'mail',
2575
2702
  'maximize',
2703
+ 'medical-cross',
2576
2704
  'menu',
2577
2705
  'mic-on',
2578
2706
  'mic',
2579
2707
  'minimize',
2708
+ 'minus',
2580
2709
  'more-h',
2581
2710
  'more-v',
2711
+ 'navigation-pointer',
2582
2712
  'order',
2583
2713
  'package',
2584
2714
  'paperclip',
@@ -2600,6 +2730,7 @@ export const ICON_NAMES: IconName[] = [
2600
2730
  'share',
2601
2731
  'shelf-pay',
2602
2732
  'shield-check',
2733
+ 'shopping-bag',
2603
2734
  'shutter-recording',
2604
2735
  'shutter',
2605
2736
  'sidebar',
@@ -2607,8 +2738,10 @@ export const ICON_NAMES: IconName[] = [
2607
2738
  'sound-off',
2608
2739
  'sound',
2609
2740
  'spark',
2741
+ 'star-filled',
2610
2742
  'star',
2611
2743
  'stop',
2744
+ 'store',
2612
2745
  'storefront-ai',
2613
2746
  'storefront-arrow',
2614
2747
  'storefront-check',
@@ -2622,6 +2755,7 @@ export const ICON_NAMES: IconName[] = [
2622
2755
  'upload',
2623
2756
  'user',
2624
2757
  'users-search',
2758
+ 'utensils',
2625
2759
  'visit',
2626
2760
  'warning',
2627
2761
  ];