@unif/react-native-design 0.17.0 → 0.19.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 (27) hide show
  1. package/lib/module/components/ui/Chip/Chip.js +26 -6
  2. package/lib/module/components/ui/Chip/Chip.js.map +1 -1
  3. package/lib/module/theme/ThemeProvider.js +5 -3
  4. package/lib/module/theme/ThemeProvider.js.map +1 -1
  5. package/lib/module/theme/useTheme.js +2 -1
  6. package/lib/module/theme/useTheme.js.map +1 -1
  7. package/lib/module/theme/useThemedStyles.js +48 -6
  8. package/lib/module/theme/useThemedStyles.js.map +1 -1
  9. package/lib/typescript/src/components/ui/Chip/Chip.d.ts +2 -1
  10. package/lib/typescript/src/components/ui/Chip/Chip.d.ts.map +1 -1
  11. package/lib/typescript/src/components/ui/Chip/types.d.ts +4 -0
  12. package/lib/typescript/src/components/ui/Chip/types.d.ts.map +1 -1
  13. package/lib/typescript/src/components/ui/Input/Input.d.ts +3 -3
  14. package/lib/typescript/src/components/ui/Search/Search.d.ts +3 -3
  15. package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts +3 -3
  16. package/lib/typescript/src/components/ui/Textarea/Textarea.d.ts +3 -3
  17. package/lib/typescript/src/theme/ThemeProvider.d.ts +7 -1
  18. package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -1
  19. package/lib/typescript/src/theme/useTheme.d.ts.map +1 -1
  20. package/lib/typescript/src/theme/useThemedStyles.d.ts +10 -4
  21. package/lib/typescript/src/theme/useThemedStyles.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/src/components/ui/Chip/Chip.tsx +45 -5
  24. package/src/components/ui/Chip/types.ts +4 -0
  25. package/src/theme/ThemeProvider.tsx +13 -2
  26. package/src/theme/useTheme.ts +1 -0
  27. package/src/theme/useThemedStyles.ts +56 -6
@@ -3,15 +3,23 @@
3
3
  import React from 'react';
4
4
  import { Text, View } from 'react-native';
5
5
  import { Pressable } from 'react-native-gesture-handler';
6
- import { fixed, pressedOpacity, r, rf, useThemedStyles } from "../../../theme/index.js";
6
+ import { fixed, pressedOpacity, r, rf, useColors, useThemedStyles } from "../../../theme/index.js";
7
+ import { Spinner } from "../Spinner/index.js";
7
8
  import { makeStyles } from "./styles.js";
8
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ /** 处理中 chip 的透明度 —— 比 disabled(0.5)亮、比按下(pressedOpacity)暗:
11
+ * 「正在办」既要压下去,又不能和「不能点」长一样(那两者只靠 spinner 区分就太弱了)。 */
12
+ const busyOpacity = 0.6;
13
+ /** busy spinner 直径 —— 与调用方常用的 leading icon(12)等大,顶替时不改 chip 宽度。 */
14
+ const busySpinner = r(12);
15
+
9
16
  /**
10
17
  * 胶囊形可点击 chip。
11
18
  * - 默认:surface 底 + outline 细线边框,foreground 文本
12
19
  * - 选中:主色边框 + 主色文本
13
20
  * - 按下:透明度 pressedOpacity(与 ButtonBase 同源)
14
21
  * - 禁用:透明度 0.5 + 不响应 onPress
22
+ * - 处理中(`busy`):leading 换 spinner + 透明度 0.6 + 不响应二次点击
15
23
  *
16
24
  * 常用于建议 chip、筛选 pill、多选标签等。
17
25
  */
@@ -20,17 +28,26 @@ export function Chip({
20
28
  selected,
21
29
  onPress,
22
30
  disabled,
31
+ busy,
23
32
  leading,
24
33
  trailing,
25
34
  style,
26
35
  testID
27
36
  }) {
37
+ const c = useColors();
28
38
  const styles = useThemedStyles(makeStyles);
39
+ // 处理中把 spinner 放进 leading 位(有 leading 就顶掉它):label 必须留着 —— 换掉它 chip
40
+ // 会塌成一个圆点,同排 chip 集体重排。spinner 跟随文本色,不在未选中的 chip 上凭空冒主色。
41
+ const lead = busy ? /*#__PURE__*/_jsx(Spinner, {
42
+ size: busySpinner,
43
+ thickness: r(1.5),
44
+ color: selected ? c.primary : c.foreground
45
+ }) : leading;
29
46
  const inner = /*#__PURE__*/_jsxs(View, {
30
47
  style: [styles.chip, selected && styles.chipOn, style],
31
48
  testID: onPress ? undefined : testID,
32
- children: [leading != null ? /*#__PURE__*/_jsx(View, {
33
- children: leading
49
+ children: [lead != null ? /*#__PURE__*/_jsx(View, {
50
+ children: lead
34
51
  }) : null, /*#__PURE__*/_jsx(Text, {
35
52
  style: [styles.text, selected && styles.textOn],
36
53
  numberOfLines: 1,
@@ -43,13 +60,16 @@ export function Chip({
43
60
  // [M-7] chip 内容高 ≈ 2×space[3] + xs 行高 ≈ 34pt < 44pt
44
61
  // Pressable 是外壳,hitSlop 向外补足到 fixed.hitTarget
45
62
  const chipHitSlopV = Math.max(0, Math.round((fixed.hitTarget - (2 * r(8) + rf(13) * 1.4)) / 2));
63
+ // 处理中同样不响应:chip 的高频用法是「点一下发起一次请求」,放行二次点击就是重复提交。
64
+ const inactive = !!disabled || !!busy;
46
65
  return /*#__PURE__*/_jsx(Pressable, {
47
66
  onPress: onPress,
48
- disabled: disabled,
67
+ disabled: inactive,
49
68
  accessibilityRole: "button",
50
69
  accessibilityState: {
51
70
  selected: !!selected,
52
- disabled: !!disabled
71
+ disabled: inactive,
72
+ busy: !!busy
53
73
  },
54
74
  accessibilityLabel: label,
55
75
  testID: testID,
@@ -63,7 +83,7 @@ export function Chip({
63
83
  pressed
64
84
  }) => [{
65
85
  alignSelf: 'flex-start',
66
- opacity: disabled ? 0.5 : pressed ? pressedOpacity : 1
86
+ opacity: disabled ? 0.5 : busy ? busyOpacity : pressed ? pressedOpacity : 1
67
87
  }],
68
88
  children: inner
69
89
  });
@@ -1 +1 @@
1
- {"version":3,"names":["React","Text","View","Pressable","fixed","pressedOpacity","r","rf","useThemedStyles","makeStyles","jsx","_jsx","jsxs","_jsxs","Chip","label","selected","onPress","disabled","leading","trailing","style","testID","styles","inner","chip","chipOn","undefined","children","text","textOn","numberOfLines","chipHitSlopV","Math","max","round","hitTarget","accessibilityRole","accessibilityState","accessibilityLabel","hitSlop","top","bottom","left","right","pressed","alignSelf","opacity"],"sourceRoot":"../../../../../src","sources":["components/ui/Chip/Chip.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,EAAEC,IAAI,QAAQ,cAAc;AACzC,SAASC,SAAS,QAAQ,8BAA8B;AACxD,SAASC,KAAK,EAAEC,cAAc,EAAEC,CAAC,EAAEC,EAAE,EAAEC,eAAe,QAAQ,yBAAgB;AAC9E,SAASC,UAAU,QAAQ,aAAU;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAGtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,IAAIA,CAAC;EACnBC,KAAK;EACLC,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,KAAK;EACLC;AACS,CAAC,EAAqB;EAC/B,MAAMC,MAAM,GAAGf,eAAe,CAACC,UAAU,CAAC;EAC1C,MAAMe,KAAK,gBACTX,KAAA,CAACX,IAAI;IACHmB,KAAK,EAAE,CAACE,MAAM,CAACE,IAAI,EAAET,QAAQ,IAAIO,MAAM,CAACG,MAAM,EAAEL,KAAK,CAAE;IACvDC,MAAM,EAAEL,OAAO,GAAGU,SAAS,GAAGL,MAAO;IAAAM,QAAA,GAEpCT,OAAO,IAAI,IAAI,gBAAGR,IAAA,CAACT,IAAI;MAAA0B,QAAA,EAAET;IAAO,CAAO,CAAC,GAAG,IAAI,eAChDR,IAAA,CAACV,IAAI;MAACoB,KAAK,EAAE,CAACE,MAAM,CAACM,IAAI,EAAEb,QAAQ,IAAIO,MAAM,CAACO,MAAM,CAAE;MAACC,aAAa,EAAE,CAAE;MAAAH,QAAA,EACrEb;IAAK,CACF,CAAC,EACNK,QAAQ,IAAI,IAAI,gBAAGT,IAAA,CAACT,IAAI;MAAA0B,QAAA,EAAER;IAAQ,CAAO,CAAC,GAAG,IAAI;EAAA,CAC9C,CACP;EAED,IAAIH,OAAO,EAAE;IACX;IACA;IACA,MAAMe,YAAY,GAAGC,IAAI,CAACC,GAAG,CAC3B,CAAC,EACDD,IAAI,CAACE,KAAK,CAAC,CAAC/B,KAAK,CAACgC,SAAS,IAAI,CAAC,GAAG9B,CAAC,CAAC,CAAC,CAAC,GAAGC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAC9D,CAAC;IACD,oBACEI,IAAA,CAACR,SAAS;MACRc,OAAO,EAAEA,OAAQ;MACjBC,QAAQ,EAAEA,QAAS;MACnBmB,iBAAiB,EAAC,QAAQ;MAC1BC,kBAAkB,EAAE;QAAEtB,QAAQ,EAAE,CAAC,CAACA,QAAQ;QAAEE,QAAQ,EAAE,CAAC,CAACA;MAAS,CAAE;MACnEqB,kBAAkB,EAAExB,KAAM;MAC1BO,MAAM,EAAEA,MAAO;MACfkB,OAAO,EAAE;QAAEC,GAAG,EAAET,YAAY;QAAEU,MAAM,EAAEV,YAAY;QAAEW,IAAI,EAAE,CAAC;QAAEC,KAAK,EAAE;MAAE,CAAE;MACxEvB,KAAK,EAAEA,CAAC;QAAEwB;MAAQ,CAAC,KAAK,CACtB;QACEC,SAAS,EAAE,YAAY;QACvBC,OAAO,EAAE7B,QAAQ,GAAG,GAAG,GAAG2B,OAAO,GAAGxC,cAAc,GAAG;MACvD,CAAC,CACD;MAAAuB,QAAA,EAEDJ;IAAK,CACG,CAAC;EAEhB;EACA,OAAOA,KAAK;AACd","ignoreList":[]}
1
+ {"version":3,"names":["React","Text","View","Pressable","fixed","pressedOpacity","r","rf","useColors","useThemedStyles","Spinner","makeStyles","jsx","_jsx","jsxs","_jsxs","busyOpacity","busySpinner","Chip","label","selected","onPress","disabled","busy","leading","trailing","style","testID","c","styles","lead","size","thickness","color","primary","foreground","inner","chip","chipOn","undefined","children","text","textOn","numberOfLines","chipHitSlopV","Math","max","round","hitTarget","inactive","accessibilityRole","accessibilityState","accessibilityLabel","hitSlop","top","bottom","left","right","pressed","alignSelf","opacity"],"sourceRoot":"../../../../../src","sources":["components/ui/Chip/Chip.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,EAAEC,IAAI,QAAQ,cAAc;AACzC,SAASC,SAAS,QAAQ,8BAA8B;AACxD,SACEC,KAAK,EACLC,cAAc,EACdC,CAAC,EACDC,EAAE,EACFC,SAAS,EACTC,eAAe,QACV,yBAAgB;AACvB,SAASC,OAAO,QAAQ,qBAAY;AACpC,SAASC,UAAU,QAAQ,aAAU;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAGtC;AACA;AACA,MAAMC,WAAW,GAAG,GAAG;AACvB;AACA,MAAMC,WAAW,GAAGX,CAAC,CAAC,EAAE,CAAC;;AAEzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASY,IAAIA,CAAC;EACnBC,KAAK;EACLC,QAAQ;EACRC,OAAO;EACPC,QAAQ;EACRC,IAAI;EACJC,OAAO;EACPC,QAAQ;EACRC,KAAK;EACLC;AACS,CAAC,EAAqB;EAC/B,MAAMC,CAAC,GAAGpB,SAAS,CAAC,CAAC;EACrB,MAAMqB,MAAM,GAAGpB,eAAe,CAACE,UAAU,CAAC;EAC1C;EACA;EACA,MAAMmB,IAAI,GAAGP,IAAI,gBACfV,IAAA,CAACH,OAAO;IACNqB,IAAI,EAAEd,WAAY;IAClBe,SAAS,EAAE1B,CAAC,CAAC,GAAG,CAAE;IAClB2B,KAAK,EAAEb,QAAQ,GAAGQ,CAAC,CAACM,OAAO,GAAGN,CAAC,CAACO;EAAW,CAC5C,CAAC,GAEFX,OACD;EACD,MAAMY,KAAK,gBACTrB,KAAA,CAACb,IAAI;IACHwB,KAAK,EAAE,CAACG,MAAM,CAACQ,IAAI,EAAEjB,QAAQ,IAAIS,MAAM,CAACS,MAAM,EAAEZ,KAAK,CAAE;IACvDC,MAAM,EAAEN,OAAO,GAAGkB,SAAS,GAAGZ,MAAO;IAAAa,QAAA,GAEpCV,IAAI,IAAI,IAAI,gBAAGjB,IAAA,CAACX,IAAI;MAAAsC,QAAA,EAAEV;IAAI,CAAO,CAAC,GAAG,IAAI,eAC1CjB,IAAA,CAACZ,IAAI;MAACyB,KAAK,EAAE,CAACG,MAAM,CAACY,IAAI,EAAErB,QAAQ,IAAIS,MAAM,CAACa,MAAM,CAAE;MAACC,aAAa,EAAE,CAAE;MAAAH,QAAA,EACrErB;IAAK,CACF,CAAC,EACNM,QAAQ,IAAI,IAAI,gBAAGZ,IAAA,CAACX,IAAI;MAAAsC,QAAA,EAAEf;IAAQ,CAAO,CAAC,GAAG,IAAI;EAAA,CAC9C,CACP;EAED,IAAIJ,OAAO,EAAE;IACX;IACA;IACA,MAAMuB,YAAY,GAAGC,IAAI,CAACC,GAAG,CAC3B,CAAC,EACDD,IAAI,CAACE,KAAK,CAAC,CAAC3C,KAAK,CAAC4C,SAAS,IAAI,CAAC,GAAG1C,CAAC,CAAC,CAAC,CAAC,GAAGC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAC9D,CAAC;IACD;IACA,MAAM0C,QAAQ,GAAG,CAAC,CAAC3B,QAAQ,IAAI,CAAC,CAACC,IAAI;IACrC,oBACEV,IAAA,CAACV,SAAS;MACRkB,OAAO,EAAEA,OAAQ;MACjBC,QAAQ,EAAE2B,QAAS;MACnBC,iBAAiB,EAAC,QAAQ;MAC1BC,kBAAkB,EAAE;QAClB/B,QAAQ,EAAE,CAAC,CAACA,QAAQ;QACpBE,QAAQ,EAAE2B,QAAQ;QAClB1B,IAAI,EAAE,CAAC,CAACA;MACV,CAAE;MACF6B,kBAAkB,EAAEjC,KAAM;MAC1BQ,MAAM,EAAEA,MAAO;MACf0B,OAAO,EAAE;QAAEC,GAAG,EAAEV,YAAY;QAAEW,MAAM,EAAEX,YAAY;QAAEY,IAAI,EAAE,CAAC;QAAEC,KAAK,EAAE;MAAE,CAAE;MACxE/B,KAAK,EAAEA,CAAC;QAAEgC;MAAQ,CAAC,KAAK,CACtB;QACEC,SAAS,EAAE,YAAY;QACvBC,OAAO,EAAEtC,QAAQ,GACb,GAAG,GACHC,IAAI,GACFP,WAAW,GACX0C,OAAO,GACLrD,cAAc,GACd;MACV,CAAC,CACD;MAAAmC,QAAA,EAEDJ;IAAK,CACG,CAAC;EAEhB;EACA,OAAOA,KAAK;AACd","ignoreList":[]}
@@ -8,7 +8,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
8
8
  export const ThemeContext = /*#__PURE__*/createContext(null);
9
9
  export function ThemeProvider({
10
10
  children,
11
- forceScheme
11
+ forceScheme,
12
+ fontScale = 1
12
13
  }) {
13
14
  const sysScheme = useColorScheme();
14
15
  const scheme = forceScheme ?? (sysScheme === 'dark' ? 'dark' : 'light');
@@ -18,8 +19,9 @@ export function ThemeProvider({
18
19
  const value = useMemo(() => ({
19
20
  scheme,
20
21
  colors: scheme === 'dark' ? darkColors : lightColors,
21
- shadow: scheme === 'dark' ? darkShadow : lightShadow
22
- }), [scheme]);
22
+ shadow: scheme === 'dark' ? darkShadow : lightShadow,
23
+ fontScale
24
+ }), [scheme, fontScale]);
23
25
  return /*#__PURE__*/_jsx(ThemeContext.Provider, {
24
26
  value: value,
25
27
  children: children
@@ -1 +1 @@
1
- {"version":3,"names":["React","createContext","useMemo","useColorScheme","lightColors","darkColors","lightShadow","darkShadow","jsx","_jsx","ThemeContext","ThemeProvider","children","forceScheme","sysScheme","scheme","value","colors","shadow","Provider"],"sourceRoot":"../../../src","sources":["theme/ThemeProvider.tsx"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,aAAa,EAAEC,OAAO,QAAQ,OAAO;AACrD,SAASC,cAAc,QAAQ,cAAc;AAC7C,SAASC,WAAW,EAAEC,UAAU,QAA0B,aAAU;AACpE,SAASC,WAAW,EAAEC,UAAU,QAA2B,aAAU;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAUtE,OAAO,MAAMC,YAAY,gBAAGT,aAAa,CAA2B,IAAI,CAAC;AAQzE,OAAO,SAASU,aAAaA,CAAC;EAAEC,QAAQ;EAAEC;AAAgC,CAAC,EAAE;EAC3E,MAAMC,SAAS,GAAGX,cAAc,CAAC,CAAC;EAClC,MAAMY,MAAmB,GACvBF,WAAW,KAAKC,SAAS,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;;EAE1D;EACA;EACA,MAAME,KAAK,GAAGd,OAAO,CACnB,OAAO;IACLa,MAAM;IACNE,MAAM,EAAEF,MAAM,KAAK,MAAM,GAAGV,UAAU,GAAGD,WAAW;IACpDc,MAAM,EAAEH,MAAM,KAAK,MAAM,GAAGR,UAAU,GAAGD;EAC3C,CAAC,CAAC,EACF,CAACS,MAAM,CACT,CAAC;EAED,oBACEN,IAAA,CAACC,YAAY,CAACS,QAAQ;IAACH,KAAK,EAAEA,KAAM;IAAAJ,QAAA,EAAEA;EAAQ,CAAwB,CAAC;AAE3E","ignoreList":[]}
1
+ {"version":3,"names":["React","createContext","useMemo","useColorScheme","lightColors","darkColors","lightShadow","darkShadow","jsx","_jsx","ThemeContext","ThemeProvider","children","forceScheme","fontScale","sysScheme","scheme","value","colors","shadow","Provider"],"sourceRoot":"../../../src","sources":["theme/ThemeProvider.tsx"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,aAAa,EAAEC,OAAO,QAAQ,OAAO;AACrD,SAASC,cAAc,QAAQ,cAAc;AAC7C,SAASC,WAAW,EAAEC,UAAU,QAA0B,aAAU;AACpE,SAASC,WAAW,EAAEC,UAAU,QAA2B,aAAU;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAatE,OAAO,MAAMC,YAAY,gBAAGT,aAAa,CAA2B,IAAI,CAAC;AAWzE,OAAO,SAASU,aAAaA,CAAC;EAC5BC,QAAQ;EACRC,WAAW;EACXC,SAAS,GAAG;AACM,CAAC,EAAE;EACrB,MAAMC,SAAS,GAAGZ,cAAc,CAAC,CAAC;EAClC,MAAMa,MAAmB,GACvBH,WAAW,KAAKE,SAAS,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;;EAE1D;EACA;EACA,MAAME,KAAK,GAAGf,OAAO,CACnB,OAAO;IACLc,MAAM;IACNE,MAAM,EAAEF,MAAM,KAAK,MAAM,GAAGX,UAAU,GAAGD,WAAW;IACpDe,MAAM,EAAEH,MAAM,KAAK,MAAM,GAAGT,UAAU,GAAGD,WAAW;IACpDQ;EACF,CAAC,CAAC,EACF,CAACE,MAAM,EAAEF,SAAS,CACpB,CAAC;EAED,oBACEL,IAAA,CAACC,YAAY,CAACU,QAAQ;IAACH,KAAK,EAAEA,KAAM;IAAAL,QAAA,EAAEA;EAAQ,CAAwB,CAAC;AAE3E","ignoreList":[]}
@@ -7,7 +7,8 @@ import { lightShadow } from "./shadow.js";
7
7
  const FALLBACK = {
8
8
  scheme: 'light',
9
9
  colors: lightColors,
10
- shadow: lightShadow
10
+ shadow: lightShadow,
11
+ fontScale: 1
11
12
  };
12
13
 
13
14
  // 静默回退而非 throw:FALLBACK 是模块级稳定引用,useThemedStyles 缓存契约不受影响。
@@ -1 +1 @@
1
- {"version":3,"names":["useContext","ThemeContext","lightColors","lightShadow","FALLBACK","scheme","colors","shadow","_warnedMissingProvider","useTheme","ctx","undefined","__DEV__","console","warn","useColors","useShadow"],"sourceRoot":"../../../src","sources":["theme/useTheme.ts"],"mappings":";;AAAA,SAASA,UAAU,QAAQ,OAAO;AAClC,SAASC,YAAY,QAAgC,oBAAiB;AACtE,SAASC,WAAW,QAAQ,aAAU;AACtC,SAASC,WAAW,QAAQ,aAAU;AAEtC,MAAMC,QAA2B,GAAG;EAClCC,MAAM,EAAE,OAAO;EACfC,MAAM,EAAEJ,WAAW;EACnBK,MAAM,EAAEJ;AACV,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,IAAIK,sBAAsB,GAAG,KAAK;AAElC,OAAO,SAASC,QAAQA,CAAA,EAAsB;EAC5C,MAAMC,GAAG,GAAGV,UAAU,CAACC,YAAY,CAAC;EACpC,IAAIS,GAAG,KAAKC,SAAS,IAAI,CAACH,sBAAsB,EAAE;IAChDA,sBAAsB,GAAG,IAAI;IAC7B,IAAI,OAAOI,OAAO,KAAK,WAAW,IAAIA,OAAO,EAAE;MAC7CC,OAAO,CAACC,IAAI,CACV,mFACF,CAAC;IACH;EACF;EACA,OAAOJ,GAAG,IAAIN,QAAQ;AACxB;AAEA,OAAO,SAASW,SAASA,CAAA,EAAG;EAC1B,OAAON,QAAQ,CAAC,CAAC,CAACH,MAAM;AAC1B;AAEA,OAAO,SAASU,SAASA,CAAA,EAAG;EAC1B,OAAOP,QAAQ,CAAC,CAAC,CAACF,MAAM;AAC1B","ignoreList":[]}
1
+ {"version":3,"names":["useContext","ThemeContext","lightColors","lightShadow","FALLBACK","scheme","colors","shadow","fontScale","_warnedMissingProvider","useTheme","ctx","undefined","__DEV__","console","warn","useColors","useShadow"],"sourceRoot":"../../../src","sources":["theme/useTheme.ts"],"mappings":";;AAAA,SAASA,UAAU,QAAQ,OAAO;AAClC,SAASC,YAAY,QAAgC,oBAAiB;AACtE,SAASC,WAAW,QAAQ,aAAU;AACtC,SAASC,WAAW,QAAQ,aAAU;AAEtC,MAAMC,QAA2B,GAAG;EAClCC,MAAM,EAAE,OAAO;EACfC,MAAM,EAAEJ,WAAW;EACnBK,MAAM,EAAEJ,WAAW;EACnBK,SAAS,EAAE;AACb,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,IAAIC,sBAAsB,GAAG,KAAK;AAElC,OAAO,SAASC,QAAQA,CAAA,EAAsB;EAC5C,MAAMC,GAAG,GAAGX,UAAU,CAACC,YAAY,CAAC;EACpC,IAAIU,GAAG,KAAKC,SAAS,IAAI,CAACH,sBAAsB,EAAE;IAChDA,sBAAsB,GAAG,IAAI;IAC7B,IAAI,OAAOI,OAAO,KAAK,WAAW,IAAIA,OAAO,EAAE;MAC7CC,OAAO,CAACC,IAAI,CACV,mFACF,CAAC;IACH;EACF;EACA,OAAOJ,GAAG,IAAIP,QAAQ;AACxB;AAEA,OAAO,SAASY,SAASA,CAAA,EAAG;EAC1B,OAAON,QAAQ,CAAC,CAAC,CAACJ,MAAM;AAC1B;AAEA,OAAO,SAASW,SAASA,CAAA,EAAG;EAC1B,OAAOP,QAAQ,CAAC,CAAC,CAACH,MAAM;AAC1B","ignoreList":[]}
@@ -6,18 +6,60 @@ import { useTheme } from "./useTheme.js";
6
6
  /** RN 0.85 strict-api 不再导出 `StyleSheet.NamedStyles`,这里本地保留同名约束:
7
7
  * `{ [k]: ViewStyle | TextStyle | ImageStyle }` —— 给 maker 返回值兜底。 */
8
8
 
9
+ /** 应用级字号缩放只作用于文字三属性 —— 与 RN allowFontScaling 的原生缩放
10
+ * 范围一致(只缩文字,不缩 padding / 高度等布局尺寸)。无字号系属性的
11
+ * style 返回原引用。strict-api 下 TextStyle 只读,用条件展开构造新对象。 */
12
+ function scaleTextStyle(style, factor) {
13
+ const {
14
+ fontSize,
15
+ lineHeight,
16
+ letterSpacing
17
+ } = style;
18
+ if (typeof fontSize !== 'number' && typeof lineHeight !== 'number' && typeof letterSpacing !== 'number') {
19
+ return style;
20
+ }
21
+ return {
22
+ ...style,
23
+ ...(typeof fontSize === 'number' ? {
24
+ fontSize: fontSize * factor
25
+ } : null),
26
+ ...(typeof lineHeight === 'number' ? {
27
+ lineHeight: lineHeight * factor
28
+ } : null),
29
+ ...(typeof letterSpacing === 'number' ? {
30
+ letterSpacing: letterSpacing * factor
31
+ } : null)
32
+ };
33
+ }
34
+
35
+ /** maker 产物按 fontScale 缩放字号系属性。factor = 1 时恒等返回**原引用**——
36
+ * 未接入 fontScale 的消费方(web 文档站等)行为与引用完全不变。
37
+ * 导出仅供单测,不进 barrel。 */
38
+ export function scaleNamedStyles(styles, factor) {
39
+ if (factor === 1) return styles;
40
+ const out = {};
41
+ for (const [key, style] of Object.entries(styles)) {
42
+ // ViewStyle / ImageStyle 无字号三属性,按 TextStyle 探测后恒等返回原引用。
43
+ out[key] = style && typeof style === 'object' ? scaleTextStyle(style, factor) : style;
44
+ }
45
+ return out;
46
+ }
47
+
9
48
  /**
10
- * 接收 (colors, shadow) => StyleSheet 工厂,返回当前主题对应的 themed StyleSheet
49
+ * 接收 (colors, shadow) => StyleSheet 工厂,返回当前主题对应的 themed StyleSheet,
50
+ * 并按 ThemeProvider 的 fontScale 缩放字号系属性(fontSize / lineHeight /
51
+ * letterSpacing;fontScale = 1 时恒等)。
11
52
  *
12
- * 缓存依赖 [colors, shadow, maker]。`maker` 必须定义在模块顶层(不要写在组件内联),
13
- * 否则引用每次变,缓存失效。ThemeProvider 通过 useMemo([scheme]) 保证主题不变时
14
- * colors / shadow 引用稳定。
53
+ * 缓存依赖 [colors, shadow, fontScale, maker]。`maker` 必须定义在模块顶层
54
+ * (不要写在组件内联),否则引用每次变,缓存失效。ThemeProvider 通过
55
+ * useMemo([scheme, fontScale]) 保证主题不变时 colors / shadow 引用稳定。
15
56
  */
16
57
  export function useThemedStyles(maker) {
17
58
  const {
18
59
  colors,
19
- shadow
60
+ shadow,
61
+ fontScale
20
62
  } = useTheme();
21
- return useMemo(() => maker(colors, shadow), [colors, shadow, maker]);
63
+ return useMemo(() => scaleNamedStyles(maker(colors, shadow), fontScale), [colors, shadow, fontScale, maker]);
22
64
  }
23
65
  //# sourceMappingURL=useThemedStyles.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useMemo","useTheme","useThemedStyles","maker","colors","shadow"],"sourceRoot":"../../../src","sources":["theme/useThemedStyles.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,OAAO;AAI/B,SAASC,QAAQ,QAAQ,eAAY;;AAErC;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BC,KAAqB,EAClB;EACH,MAAM;IAAEC,MAAM;IAAEC;EAAO,CAAC,GAAGJ,QAAQ,CAAC,CAAC;EACrC,OAAOD,OAAO,CAAC,MAAMG,KAAK,CAACC,MAAM,EAAEC,MAAM,CAAC,EAAE,CAACD,MAAM,EAAEC,MAAM,EAAEF,KAAK,CAAC,CAAC;AACtE","ignoreList":[]}
1
+ {"version":3,"names":["useMemo","useTheme","scaleTextStyle","style","factor","fontSize","lineHeight","letterSpacing","scaleNamedStyles","styles","out","key","Object","entries","useThemedStyles","maker","colors","shadow","fontScale"],"sourceRoot":"../../../src","sources":["theme/useThemedStyles.ts"],"mappings":";;AAAA,SAASA,OAAO,QAAQ,OAAO;AAI/B,SAASC,QAAQ,QAAQ,eAAY;;AAErC;AACA;;AAQA;AACA;AACA;AACA,SAASC,cAAcA,CAACC,KAAgB,EAAEC,MAAc,EAAa;EACnE,MAAM;IAAEC,QAAQ;IAAEC,UAAU;IAAEC;EAAc,CAAC,GAAGJ,KAAK;EACrD,IACE,OAAOE,QAAQ,KAAK,QAAQ,IAC5B,OAAOC,UAAU,KAAK,QAAQ,IAC9B,OAAOC,aAAa,KAAK,QAAQ,EACjC;IACA,OAAOJ,KAAK;EACd;EACA,OAAO;IACL,GAAGA,KAAK;IACR,IAAI,OAAOE,QAAQ,KAAK,QAAQ,GAAG;MAAEA,QAAQ,EAAEA,QAAQ,GAAGD;IAAO,CAAC,GAAG,IAAI,CAAC;IAC1E,IAAI,OAAOE,UAAU,KAAK,QAAQ,GAC9B;MAAEA,UAAU,EAAEA,UAAU,GAAGF;IAAO,CAAC,GACnC,IAAI,CAAC;IACT,IAAI,OAAOG,aAAa,KAAK,QAAQ,GACjC;MAAEA,aAAa,EAAEA,aAAa,GAAGH;IAAO,CAAC,GACzC,IAAI;EACV,CAAC;AACH;;AAEA;AACA;AACA;AACA,OAAO,SAASI,gBAAgBA,CAC9BC,MAAS,EACTL,MAAc,EACX;EACH,IAAIA,MAAM,KAAK,CAAC,EAAE,OAAOK,MAAM;EAC/B,MAAMC,GAAuD,GAAG,CAAC,CAAC;EAClE,KAAK,MAAM,CAACC,GAAG,EAAER,KAAK,CAAC,IAAIS,MAAM,CAACC,OAAO,CACvCJ,MACF,CAAC,EAAE;IACD;IACAC,GAAG,CAACC,GAAG,CAAC,GACNR,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,GAC9BD,cAAc,CAACC,KAAK,EAAeC,MAAM,CAAC,GAC1CD,KAAK;EACb;EACA,OAAOO,GAAG;AACZ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASI,eAAeA,CAC7BC,KAAqB,EAClB;EACH,MAAM;IAAEC,MAAM;IAAEC,MAAM;IAAEC;EAAU,CAAC,GAAGjB,QAAQ,CAAC,CAAC;EAChD,OAAOD,OAAO,CACZ,MAAMQ,gBAAgB,CAACO,KAAK,CAACC,MAAM,EAAEC,MAAM,CAAC,EAAEC,SAAS,CAAC,EACxD,CAACF,MAAM,EAAEC,MAAM,EAAEC,SAAS,EAAEH,KAAK,CACnC,CAAC;AACH","ignoreList":[]}
@@ -6,8 +6,9 @@ import type { ChipProps } from './types';
6
6
  * - 选中:主色边框 + 主色文本
7
7
  * - 按下:透明度 pressedOpacity(与 ButtonBase 同源)
8
8
  * - 禁用:透明度 0.5 + 不响应 onPress
9
+ * - 处理中(`busy`):leading 换 spinner + 透明度 0.6 + 不响应二次点击
9
10
  *
10
11
  * 常用于建议 chip、筛选 pill、多选标签等。
11
12
  */
12
- export declare function Chip({ label, selected, onPress, disabled, leading, trailing, style, testID, }: ChipProps): React.JSX.Element;
13
+ export declare function Chip({ label, selected, onPress, disabled, busy, leading, trailing, style, testID, }: ChipProps): React.JSX.Element;
13
14
  //# sourceMappingURL=Chip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,GACP,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA2C/B"}
1
+ {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAQzC;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,GACP,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAmE/B"}
@@ -6,6 +6,10 @@ export type ChipProps = {
6
6
  onPress?: () => void;
7
7
  /** 整体禁用:opacity 0.5 + 不响应 onPress + accessibilityState.disabled */
8
8
  disabled?: boolean;
9
+ /** 处理中(点了、请求在飞):leading 位换 spinner + opacity 0.6 + 不响应二次点击 +
10
+ * accessibilityState.busy。label 保留 —— 换掉它 chip 会塌成一个圆点、整行跟着重排。
11
+ * 与 `disabled` 的分工:disabled = 现在不能点(更暗、无 spinner),busy = 正在办。 */
12
+ busy?: boolean;
9
13
  /** 可选的前置插槽 —— 如 <Icon name="spark" /> */
10
14
  leading?: ReactNode;
11
15
  /** 可选的后置插槽 —— 如一个小的 × 关闭按钮 */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Chip/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;sEAEkE;IAClE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yCAAyC;IACzC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
@@ -136,7 +136,7 @@ export declare const Input: import("react").ForwardRefExoticComponent<Omit<Reado
136
136
  pointerEvents?: ("auto" | "box-none" | "box-only" | "none") | undefined;
137
137
  removeClippedSubviews?: boolean | undefined;
138
138
  experimental_accessibilityOrder?: Array<string> | undefined;
139
- }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
139
+ }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
140
140
  disableKeyboardShortcuts?: boolean | undefined;
141
141
  clearButtonMode?: ("never" | "while-editing" | "unless-editing" | "always") | undefined;
142
142
  clearTextOnFocus?: boolean | undefined;
@@ -153,7 +153,7 @@ export declare const Input: import("react").ForwardRefExoticComponent<Omit<Reado
153
153
  lineBreakStrategyIOS?: ("none" | "standard" | "hangul-word" | "push-out") | undefined;
154
154
  lineBreakModeIOS?: ("wordWrapping" | "char" | "clip" | "head" | "middle" | "tail") | undefined;
155
155
  smartInsertDelete?: boolean | undefined;
156
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
156
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
157
157
  cursorColor?: import("react-native").ColorValue | undefined;
158
158
  selectionHandleColor?: import("react-native").ColorValue | undefined;
159
159
  disableFullscreenUI?: boolean | undefined;
@@ -166,7 +166,7 @@ export declare const Input: import("react").ForwardRefExoticComponent<Omit<Reado
166
166
  showSoftInputOnFocus?: boolean | undefined;
167
167
  textBreakStrategy?: ("simple" | "highQuality" | "balanced") | undefined;
168
168
  underlineColorAndroid?: import("react-native").ColorValue | undefined;
169
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
169
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
170
170
  experimental_acceptDragAndDropTypes?: ReadonlyArray<string> | undefined;
171
171
  autoCapitalize?: import("react-native").AutoCapitalize | undefined;
172
172
  autoComplete?: ("additional-name" | "address-line1" | "address-line2" | "birthdate-day" | "birthdate-full" | "birthdate-month" | "birthdate-year" | "cc-csc" | "cc-exp" | "cc-exp-day" | "cc-exp-month" | "cc-exp-year" | "cc-number" | "cc-name" | "cc-given-name" | "cc-middle-name" | "cc-family-name" | "cc-type" | "country" | "current-password" | "email" | "family-name" | "gender" | "given-name" | "honorific-prefix" | "honorific-suffix" | "name" | "name-family" | "name-given" | "name-middle" | "name-middle-initial" | "name-prefix" | "name-suffix" | "new-password" | "nickname" | "one-time-code" | "organization" | "organization-title" | "password" | "password-new" | "postal-address" | "postal-address-country" | "postal-address-extended" | "postal-address-extended-postal-code" | "postal-address-locality" | "postal-address-region" | "postal-code" | "street-address" | "sms-otp" | "tel" | "tel-country-code" | "tel-national" | "tel-device" | "url" | "username" | "username-new" | "off") | undefined;
@@ -133,7 +133,7 @@ export declare const Search: React.ForwardRefExoticComponent<Omit<Readonly<Omit<
133
133
  pointerEvents?: ("auto" | "box-none" | "box-only" | "none") | undefined;
134
134
  removeClippedSubviews?: boolean | undefined;
135
135
  experimental_accessibilityOrder?: Array<string> | undefined;
136
- }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
136
+ }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
137
137
  disableKeyboardShortcuts?: boolean | undefined;
138
138
  clearButtonMode?: ("never" | "while-editing" | "unless-editing" | "always") | undefined;
139
139
  clearTextOnFocus?: boolean | undefined;
@@ -150,7 +150,7 @@ export declare const Search: React.ForwardRefExoticComponent<Omit<Readonly<Omit<
150
150
  lineBreakStrategyIOS?: ("none" | "standard" | "hangul-word" | "push-out") | undefined;
151
151
  lineBreakModeIOS?: ("wordWrapping" | "char" | "clip" | "head" | "middle" | "tail") | undefined;
152
152
  smartInsertDelete?: boolean | undefined;
153
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
153
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
154
154
  cursorColor?: import("react-native").ColorValue | undefined;
155
155
  selectionHandleColor?: import("react-native").ColorValue | undefined;
156
156
  disableFullscreenUI?: boolean | undefined;
@@ -163,7 +163,7 @@ export declare const Search: React.ForwardRefExoticComponent<Omit<Readonly<Omit<
163
163
  showSoftInputOnFocus?: boolean | undefined;
164
164
  textBreakStrategy?: ("simple" | "highQuality" | "balanced") | undefined;
165
165
  underlineColorAndroid?: import("react-native").ColorValue | undefined;
166
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
166
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
167
167
  experimental_acceptDragAndDropTypes?: ReadonlyArray<string> | undefined;
168
168
  autoCapitalize?: import("react-native").AutoCapitalize | undefined;
169
169
  autoComplete?: ("additional-name" | "address-line1" | "address-line2" | "birthdate-day" | "birthdate-full" | "birthdate-month" | "birthdate-year" | "cc-csc" | "cc-exp" | "cc-exp-day" | "cc-exp-month" | "cc-exp-year" | "cc-number" | "cc-name" | "cc-given-name" | "cc-middle-name" | "cc-family-name" | "cc-type" | "country" | "current-password" | "email" | "family-name" | "gender" | "given-name" | "honorific-prefix" | "honorific-suffix" | "name" | "name-family" | "name-given" | "name-middle" | "name-middle-initial" | "name-prefix" | "name-suffix" | "new-password" | "nickname" | "one-time-code" | "organization" | "organization-title" | "password" | "password-new" | "postal-address" | "postal-address-country" | "postal-address-extended" | "postal-address-extended-postal-code" | "postal-address-locality" | "postal-address-region" | "postal-code" | "street-address" | "sms-otp" | "tel" | "tel-country-code" | "tel-national" | "tel-device" | "url" | "username" | "username-new" | "off") | undefined;
@@ -144,7 +144,7 @@ export declare const TextFieldBase: React.ForwardRefExoticComponent<Readonly<Omi
144
144
  pointerEvents?: ("auto" | "box-none" | "box-only" | "none") | undefined;
145
145
  removeClippedSubviews?: boolean | undefined;
146
146
  experimental_accessibilityOrder?: Array<string> | undefined;
147
- }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
147
+ }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
148
148
  disableKeyboardShortcuts?: boolean | undefined;
149
149
  clearButtonMode?: ("never" | "while-editing" | "unless-editing" | "always") | undefined;
150
150
  clearTextOnFocus?: boolean | undefined;
@@ -161,7 +161,7 @@ export declare const TextFieldBase: React.ForwardRefExoticComponent<Readonly<Omi
161
161
  lineBreakStrategyIOS?: ("none" | "standard" | "hangul-word" | "push-out") | undefined;
162
162
  lineBreakModeIOS?: ("wordWrapping" | "char" | "clip" | "head" | "middle" | "tail") | undefined;
163
163
  smartInsertDelete?: boolean | undefined;
164
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
164
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
165
165
  cursorColor?: import("react-native").ColorValue | undefined;
166
166
  selectionHandleColor?: import("react-native").ColorValue | undefined;
167
167
  disableFullscreenUI?: boolean | undefined;
@@ -174,7 +174,7 @@ export declare const TextFieldBase: React.ForwardRefExoticComponent<Readonly<Omi
174
174
  showSoftInputOnFocus?: boolean | undefined;
175
175
  textBreakStrategy?: ("simple" | "highQuality" | "balanced") | undefined;
176
176
  underlineColorAndroid?: import("react-native").ColorValue | undefined;
177
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
177
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
178
178
  experimental_acceptDragAndDropTypes?: ReadonlyArray<string> | undefined;
179
179
  autoCapitalize?: import("react-native").AutoCapitalize | undefined;
180
180
  autoComplete?: ("additional-name" | "address-line1" | "address-line2" | "birthdate-day" | "birthdate-full" | "birthdate-month" | "birthdate-year" | "cc-csc" | "cc-exp" | "cc-exp-day" | "cc-exp-month" | "cc-exp-year" | "cc-number" | "cc-name" | "cc-given-name" | "cc-middle-name" | "cc-family-name" | "cc-type" | "country" | "current-password" | "email" | "family-name" | "gender" | "given-name" | "honorific-prefix" | "honorific-suffix" | "name" | "name-family" | "name-given" | "name-middle" | "name-middle-initial" | "name-prefix" | "name-suffix" | "new-password" | "nickname" | "one-time-code" | "organization" | "organization-title" | "password" | "password-new" | "postal-address" | "postal-address-country" | "postal-address-extended" | "postal-address-extended-postal-code" | "postal-address-locality" | "postal-address-region" | "postal-code" | "street-address" | "sms-otp" | "tel" | "tel-country-code" | "tel-national" | "tel-device" | "url" | "username" | "username-new" | "off") | undefined;
@@ -138,7 +138,7 @@ export declare const Textarea: import("react").ForwardRefExoticComponent<Omit<Re
138
138
  pointerEvents?: ("auto" | "box-none" | "box-only" | "none") | undefined;
139
139
  removeClippedSubviews?: boolean | undefined;
140
140
  experimental_accessibilityOrder?: Array<string> | undefined;
141
- }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
141
+ }>, never>>, "style" | "experimental_accessibilityOrder">, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "lineBreakStrategyIOS" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "disableKeyboardShortcuts" | "clearButtonMode" | "clearTextOnFocus" | "dataDetectorTypes" | "enablesReturnKeyAutomatically" | "inputAccessoryViewID" | "inputAccessoryViewButtonLabel" | "keyboardAppearance" | "passwordRules" | "rejectResponderTermination" | "scrollEnabled" | "spellCheck" | "textContentType" | "lineBreakModeIOS" | "smartInsertDelete" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
142
142
  disableKeyboardShortcuts?: boolean | undefined;
143
143
  clearButtonMode?: ("never" | "while-editing" | "unless-editing" | "always") | undefined;
144
144
  clearTextOnFocus?: boolean | undefined;
@@ -155,7 +155,7 @@ export declare const Textarea: import("react").ForwardRefExoticComponent<Omit<Re
155
155
  lineBreakStrategyIOS?: ("none" | "standard" | "hangul-word" | "push-out") | undefined;
156
156
  lineBreakModeIOS?: ("wordWrapping" | "char" | "clip" | "head" | "middle" | "tail") | undefined;
157
157
  smartInsertDelete?: boolean | undefined;
158
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
158
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "textBreakStrategy" | "allowFontScaling" | "maxFontSizeMultiplier" | "numberOfLines" | "onPressIn" | "onPressOut" | "cursorColor" | "selectionHandleColor" | "disableFullscreenUI" | "importantForAutofill" | "inlineImageLeft" | "inlineImagePadding" | "returnKeyLabel" | "rows" | "showSoftInputOnFocus" | "underlineColorAndroid" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
159
159
  cursorColor?: import("react-native").ColorValue | undefined;
160
160
  selectionHandleColor?: import("react-native").ColorValue | undefined;
161
161
  disableFullscreenUI?: boolean | undefined;
@@ -168,7 +168,7 @@ export declare const Textarea: import("react").ForwardRefExoticComponent<Omit<Re
168
168
  showSoftInputOnFocus?: boolean | undefined;
169
169
  textBreakStrategy?: ("simple" | "highQuality" | "balanced") | undefined;
170
170
  underlineColorAndroid?: import("react-native").ColorValue | undefined;
171
- }>, "value" | "textAlign" | "onChange" | "style" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
171
+ }>, "value" | "textAlign" | "style" | "onChange" | "onBlur" | "onFocus" | "onPress" | "selectionColor" | "allowFontScaling" | "maxFontSizeMultiplier" | "onPressIn" | "onPressOut" | "experimental_acceptDragAndDropTypes" | "autoCapitalize" | "autoComplete" | "autoCorrect" | "autoFocus" | "caretHidden" | "contextMenuHidden" | "defaultValue" | "editable" | "forwardedRef" | "enterKeyHint" | "inputMode" | "keyboardType" | "maxLength" | "multiline" | "onChangeText" | "onContentSizeChange" | "onEndEditing" | "onKeyPress" | "onSelectionChange" | "onSubmitEditing" | "onScroll" | "placeholder" | "placeholderTextColor" | "readOnly" | "returnKeyType" | "secureTextEntry" | "selection" | "selectTextOnFocus" | "blurOnSubmit" | "submitBehavior"> & Omit<Readonly<{
172
172
  experimental_acceptDragAndDropTypes?: ReadonlyArray<string> | undefined;
173
173
  autoCapitalize?: import("react-native").AutoCapitalize | undefined;
174
174
  autoComplete?: ("additional-name" | "address-line1" | "address-line2" | "birthdate-day" | "birthdate-full" | "birthdate-month" | "birthdate-year" | "cc-csc" | "cc-exp" | "cc-exp-day" | "cc-exp-month" | "cc-exp-year" | "cc-number" | "cc-name" | "cc-given-name" | "cc-middle-name" | "cc-family-name" | "cc-type" | "country" | "current-password" | "email" | "family-name" | "gender" | "given-name" | "honorific-prefix" | "honorific-suffix" | "name" | "name-family" | "name-given" | "name-middle" | "name-middle-initial" | "name-prefix" | "name-suffix" | "new-password" | "nickname" | "one-time-code" | "organization" | "organization-title" | "password" | "password-new" | "postal-address" | "postal-address-country" | "postal-address-extended" | "postal-address-extended-postal-code" | "postal-address-locality" | "postal-address-region" | "postal-code" | "street-address" | "sms-otp" | "tel" | "tel-country-code" | "tel-national" | "tel-device" | "url" | "username" | "username-new" | "off") | undefined;
@@ -6,13 +6,19 @@ export type ThemeContextValue = {
6
6
  scheme: ColorScheme;
7
7
  colors: ColorTokens;
8
8
  shadow: ShadowTokens;
9
+ /** 应用级字号缩放倍数(app 内字体大小档)。useThemedStyles 出口对
10
+ * fontSize / lineHeight / letterSpacing 生效;1 = 不缩放。 */
11
+ fontScale: number;
9
12
  };
10
13
  export declare const ThemeContext: React.Context<ThemeContextValue | null>;
11
14
  type ThemeProviderProps = {
12
15
  children: React.ReactNode;
13
16
  /** 强制使用某个 scheme(覆盖 useColorScheme)。用于测试或 settingsStore 接入。 */
14
17
  forceScheme?: ColorScheme;
18
+ /** 应用级字号缩放倍数,默认 1(不缩放)。接入方自持档位状态(persist
19
+ * store 等)并传入;变更即触发全树 themed 样式重算。 */
20
+ fontScale?: number;
15
21
  };
16
- export declare function ThemeProvider({ children, forceScheme }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
22
+ export declare function ThemeProvider({ children, forceScheme, fontScale, }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
17
23
  export {};
18
24
  //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/theme/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiC,MAAM,OAAO,CAAC;AAEtD,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,YAAY,yCAAgD,CAAC;AAE1E,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,kBAAkB,2CAmB1E"}
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/theme/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiC,MAAM,OAAO,CAAC;AAEtD,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB;4DACwD;IACxD,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,YAAY,yCAAgD,CAAC;AAE1E,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;2CACuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,WAAW,EACX,SAAa,GACd,EAAE,kBAAkB,2CAoBpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../../../src/theme/useTheme.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAiBvE,wBAAgB,QAAQ,IAAI,iBAAiB,CAW5C;AAED,wBAAgB,SAAS,mCAExB;AAED,wBAAgB,SAAS,oCAExB"}
1
+ {"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../../../src/theme/useTheme.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAkBvE,wBAAgB,QAAQ,IAAI,iBAAiB,CAW5C;AAED,wBAAgB,SAAS,mCAExB;AAED,wBAAgB,SAAS,oCAExB"}
@@ -7,12 +7,18 @@ type NamedStyles<T> = {
7
7
  [P in keyof T]: ViewStyle | TextStyle | ImageStyle;
8
8
  };
9
9
  export type StylesMaker<S extends NamedStyles<S>> = (c: ColorTokens, s: ShadowTokens) => S;
10
+ /** maker 产物按 fontScale 缩放字号系属性。factor = 1 时恒等返回**原引用**——
11
+ * 未接入 fontScale 的消费方(web 文档站等)行为与引用完全不变。
12
+ * 导出仅供单测,不进 barrel。 */
13
+ export declare function scaleNamedStyles<S extends NamedStyles<S>>(styles: S, factor: number): S;
10
14
  /**
11
- * 接收 (colors, shadow) => StyleSheet 工厂,返回当前主题对应的 themed StyleSheet
15
+ * 接收 (colors, shadow) => StyleSheet 工厂,返回当前主题对应的 themed StyleSheet,
16
+ * 并按 ThemeProvider 的 fontScale 缩放字号系属性(fontSize / lineHeight /
17
+ * letterSpacing;fontScale = 1 时恒等)。
12
18
  *
13
- * 缓存依赖 [colors, shadow, maker]。`maker` 必须定义在模块顶层(不要写在组件内联),
14
- * 否则引用每次变,缓存失效。ThemeProvider 通过 useMemo([scheme]) 保证主题不变时
15
- * colors / shadow 引用稳定。
19
+ * 缓存依赖 [colors, shadow, fontScale, maker]。`maker` 必须定义在模块顶层
20
+ * (不要写在组件内联),否则引用每次变,缓存失效。ThemeProvider 通过
21
+ * useMemo([scheme, fontScale]) 保证主题不变时 colors / shadow 引用稳定。
16
22
  */
17
23
  export declare function useThemedStyles<S extends NamedStyles<S>>(maker: StylesMaker<S>): S;
18
24
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useThemedStyles.d.ts","sourceRoot":"","sources":["../../../../src/theme/useThemedStyles.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C;sEACsE;AACtE,KAAK,WAAW,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU;CAAE,CAAC;AAE7E,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,IAAI,CAClD,CAAC,EAAE,WAAW,EACd,CAAC,EAAE,YAAY,KACZ,CAAC,CAAC;AAEP;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,EACtD,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GACpB,CAAC,CAGH"}
1
+ {"version":3,"file":"useThemedStyles.d.ts","sourceRoot":"","sources":["../../../../src/theme/useThemedStyles.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C;sEACsE;AACtE,KAAK,WAAW,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU;CAAE,CAAC;AAE7E,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,IAAI,CAClD,CAAC,EAAE,WAAW,EACd,CAAC,EAAE,YAAY,KACZ,CAAC,CAAC;AA0BP;;wBAEwB;AACxB,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,EACvD,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,GACb,CAAC,CAaH;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,EACtD,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GACpB,CAAC,CAMH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unif/react-native-design",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "Unif 设计系统:theme + icons + utils + components",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -1,16 +1,31 @@
1
1
  import React from 'react';
2
2
  import { Text, View } from 'react-native';
3
3
  import { Pressable } from 'react-native-gesture-handler';
4
- import { fixed, pressedOpacity, r, rf, useThemedStyles } from '../../../theme';
4
+ import {
5
+ fixed,
6
+ pressedOpacity,
7
+ r,
8
+ rf,
9
+ useColors,
10
+ useThemedStyles,
11
+ } from '../../../theme';
12
+ import { Spinner } from '../Spinner';
5
13
  import { makeStyles } from './styles';
6
14
  import type { ChipProps } from './types';
7
15
 
16
+ /** 处理中 chip 的透明度 —— 比 disabled(0.5)亮、比按下(pressedOpacity)暗:
17
+ * 「正在办」既要压下去,又不能和「不能点」长一样(那两者只靠 spinner 区分就太弱了)。 */
18
+ const busyOpacity = 0.6;
19
+ /** busy spinner 直径 —— 与调用方常用的 leading icon(12)等大,顶替时不改 chip 宽度。 */
20
+ const busySpinner = r(12);
21
+
8
22
  /**
9
23
  * 胶囊形可点击 chip。
10
24
  * - 默认:surface 底 + outline 细线边框,foreground 文本
11
25
  * - 选中:主色边框 + 主色文本
12
26
  * - 按下:透明度 pressedOpacity(与 ButtonBase 同源)
13
27
  * - 禁用:透明度 0.5 + 不响应 onPress
28
+ * - 处理中(`busy`):leading 换 spinner + 透明度 0.6 + 不响应二次点击
14
29
  *
15
30
  * 常用于建议 chip、筛选 pill、多选标签等。
16
31
  */
@@ -19,18 +34,31 @@ export function Chip({
19
34
  selected,
20
35
  onPress,
21
36
  disabled,
37
+ busy,
22
38
  leading,
23
39
  trailing,
24
40
  style,
25
41
  testID,
26
42
  }: ChipProps): React.JSX.Element {
43
+ const c = useColors();
27
44
  const styles = useThemedStyles(makeStyles);
45
+ // 处理中把 spinner 放进 leading 位(有 leading 就顶掉它):label 必须留着 —— 换掉它 chip
46
+ // 会塌成一个圆点,同排 chip 集体重排。spinner 跟随文本色,不在未选中的 chip 上凭空冒主色。
47
+ const lead = busy ? (
48
+ <Spinner
49
+ size={busySpinner}
50
+ thickness={r(1.5)}
51
+ color={selected ? c.primary : c.foreground}
52
+ />
53
+ ) : (
54
+ leading
55
+ );
28
56
  const inner = (
29
57
  <View
30
58
  style={[styles.chip, selected && styles.chipOn, style]}
31
59
  testID={onPress ? undefined : testID}
32
60
  >
33
- {leading != null ? <View>{leading}</View> : null}
61
+ {lead != null ? <View>{lead}</View> : null}
34
62
  <Text style={[styles.text, selected && styles.textOn]} numberOfLines={1}>
35
63
  {label}
36
64
  </Text>
@@ -45,19 +73,31 @@ export function Chip({
45
73
  0,
46
74
  Math.round((fixed.hitTarget - (2 * r(8) + rf(13) * 1.4)) / 2)
47
75
  );
76
+ // 处理中同样不响应:chip 的高频用法是「点一下发起一次请求」,放行二次点击就是重复提交。
77
+ const inactive = !!disabled || !!busy;
48
78
  return (
49
79
  <Pressable
50
80
  onPress={onPress}
51
- disabled={disabled}
81
+ disabled={inactive}
52
82
  accessibilityRole="button"
53
- accessibilityState={{ selected: !!selected, disabled: !!disabled }}
83
+ accessibilityState={{
84
+ selected: !!selected,
85
+ disabled: inactive,
86
+ busy: !!busy,
87
+ }}
54
88
  accessibilityLabel={label}
55
89
  testID={testID}
56
90
  hitSlop={{ top: chipHitSlopV, bottom: chipHitSlopV, left: 0, right: 0 }}
57
91
  style={({ pressed }) => [
58
92
  {
59
93
  alignSelf: 'flex-start',
60
- opacity: disabled ? 0.5 : pressed ? pressedOpacity : 1,
94
+ opacity: disabled
95
+ ? 0.5
96
+ : busy
97
+ ? busyOpacity
98
+ : pressed
99
+ ? pressedOpacity
100
+ : 1,
61
101
  },
62
102
  ]}
63
103
  >
@@ -7,6 +7,10 @@ export type ChipProps = {
7
7
  onPress?: () => void;
8
8
  /** 整体禁用:opacity 0.5 + 不响应 onPress + accessibilityState.disabled */
9
9
  disabled?: boolean;
10
+ /** 处理中(点了、请求在飞):leading 位换 spinner + opacity 0.6 + 不响应二次点击 +
11
+ * accessibilityState.busy。label 保留 —— 换掉它 chip 会塌成一个圆点、整行跟着重排。
12
+ * 与 `disabled` 的分工:disabled = 现在不能点(更暗、无 spinner),busy = 正在办。 */
13
+ busy?: boolean;
10
14
  /** 可选的前置插槽 —— 如 <Icon name="spark" /> */
11
15
  leading?: ReactNode;
12
16
  /** 可选的后置插槽 —— 如一个小的 × 关闭按钮 */
@@ -9,6 +9,9 @@ export type ThemeContextValue = {
9
9
  scheme: ColorScheme;
10
10
  colors: ColorTokens;
11
11
  shadow: ShadowTokens;
12
+ /** 应用级字号缩放倍数(app 内字体大小档)。useThemedStyles 出口对
13
+ * fontSize / lineHeight / letterSpacing 生效;1 = 不缩放。 */
14
+ fontScale: number;
12
15
  };
13
16
 
14
17
  export const ThemeContext = createContext<ThemeContextValue | null>(null);
@@ -17,9 +20,16 @@ type ThemeProviderProps = {
17
20
  children: React.ReactNode;
18
21
  /** 强制使用某个 scheme(覆盖 useColorScheme)。用于测试或 settingsStore 接入。 */
19
22
  forceScheme?: ColorScheme;
23
+ /** 应用级字号缩放倍数,默认 1(不缩放)。接入方自持档位状态(persist
24
+ * store 等)并传入;变更即触发全树 themed 样式重算。 */
25
+ fontScale?: number;
20
26
  };
21
27
 
22
- export function ThemeProvider({ children, forceScheme }: ThemeProviderProps) {
28
+ export function ThemeProvider({
29
+ children,
30
+ forceScheme,
31
+ fontScale = 1,
32
+ }: ThemeProviderProps) {
23
33
  const sysScheme = useColorScheme();
24
34
  const scheme: ColorScheme =
25
35
  forceScheme ?? (sysScheme === 'dark' ? 'dark' : 'light');
@@ -31,8 +41,9 @@ export function ThemeProvider({ children, forceScheme }: ThemeProviderProps) {
31
41
  scheme,
32
42
  colors: scheme === 'dark' ? darkColors : lightColors,
33
43
  shadow: scheme === 'dark' ? darkShadow : lightShadow,
44
+ fontScale,
34
45
  }),
35
- [scheme]
46
+ [scheme, fontScale]
36
47
  );
37
48
 
38
49
  return (
@@ -7,6 +7,7 @@ const FALLBACK: ThemeContextValue = {
7
7
  scheme: 'light',
8
8
  colors: lightColors,
9
9
  shadow: lightShadow,
10
+ fontScale: 1,
10
11
  };
11
12
 
12
13
  // 静默回退而非 throw:FALLBACK 是模块级稳定引用,useThemedStyles 缓存契约不受影响。
@@ -13,16 +13,66 @@ export type StylesMaker<S extends NamedStyles<S>> = (
13
13
  s: ShadowTokens
14
14
  ) => S;
15
15
 
16
+ /** 应用级字号缩放只作用于文字三属性 —— 与 RN allowFontScaling 的原生缩放
17
+ * 范围一致(只缩文字,不缩 padding / 高度等布局尺寸)。无字号系属性的
18
+ * style 返回原引用。strict-api 下 TextStyle 只读,用条件展开构造新对象。 */
19
+ function scaleTextStyle(style: TextStyle, factor: number): TextStyle {
20
+ const { fontSize, lineHeight, letterSpacing } = style;
21
+ if (
22
+ typeof fontSize !== 'number' &&
23
+ typeof lineHeight !== 'number' &&
24
+ typeof letterSpacing !== 'number'
25
+ ) {
26
+ return style;
27
+ }
28
+ return {
29
+ ...style,
30
+ ...(typeof fontSize === 'number' ? { fontSize: fontSize * factor } : null),
31
+ ...(typeof lineHeight === 'number'
32
+ ? { lineHeight: lineHeight * factor }
33
+ : null),
34
+ ...(typeof letterSpacing === 'number'
35
+ ? { letterSpacing: letterSpacing * factor }
36
+ : null),
37
+ };
38
+ }
39
+
40
+ /** maker 产物按 fontScale 缩放字号系属性。factor = 1 时恒等返回**原引用**——
41
+ * 未接入 fontScale 的消费方(web 文档站等)行为与引用完全不变。
42
+ * 导出仅供单测,不进 barrel。 */
43
+ export function scaleNamedStyles<S extends NamedStyles<S>>(
44
+ styles: S,
45
+ factor: number
46
+ ): S {
47
+ if (factor === 1) return styles;
48
+ const out: Record<string, ViewStyle | TextStyle | ImageStyle> = {};
49
+ for (const [key, style] of Object.entries(
50
+ styles as Record<string, ViewStyle | TextStyle | ImageStyle>
51
+ )) {
52
+ // ViewStyle / ImageStyle 无字号三属性,按 TextStyle 探测后恒等返回原引用。
53
+ out[key] =
54
+ style && typeof style === 'object'
55
+ ? scaleTextStyle(style as TextStyle, factor)
56
+ : style;
57
+ }
58
+ return out as S;
59
+ }
60
+
16
61
  /**
17
- * 接收 (colors, shadow) => StyleSheet 工厂,返回当前主题对应的 themed StyleSheet
62
+ * 接收 (colors, shadow) => StyleSheet 工厂,返回当前主题对应的 themed StyleSheet,
63
+ * 并按 ThemeProvider 的 fontScale 缩放字号系属性(fontSize / lineHeight /
64
+ * letterSpacing;fontScale = 1 时恒等)。
18
65
  *
19
- * 缓存依赖 [colors, shadow, maker]。`maker` 必须定义在模块顶层(不要写在组件内联),
20
- * 否则引用每次变,缓存失效。ThemeProvider 通过 useMemo([scheme]) 保证主题不变时
21
- * colors / shadow 引用稳定。
66
+ * 缓存依赖 [colors, shadow, fontScale, maker]。`maker` 必须定义在模块顶层
67
+ * (不要写在组件内联),否则引用每次变,缓存失效。ThemeProvider 通过
68
+ * useMemo([scheme, fontScale]) 保证主题不变时 colors / shadow 引用稳定。
22
69
  */
23
70
  export function useThemedStyles<S extends NamedStyles<S>>(
24
71
  maker: StylesMaker<S>
25
72
  ): S {
26
- const { colors, shadow } = useTheme();
27
- return useMemo(() => maker(colors, shadow), [colors, shadow, maker]);
73
+ const { colors, shadow, fontScale } = useTheme();
74
+ return useMemo(
75
+ () => scaleNamedStyles(maker(colors, shadow), fontScale),
76
+ [colors, shadow, fontScale, maker]
77
+ );
28
78
  }