@unif/react-native-design 0.23.0 → 0.24.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.
package/README.md CHANGED
@@ -131,6 +131,8 @@ decode 仍按 `example/README.md` 的 Android/iOS 手工矩阵标记为待执行
131
131
  ## 文档
132
132
 
133
133
  - **文档站**(快速开始 · 组件 API · 设计令牌 · 设计原则):https://unif-design.github.io/react-native-design/
134
+ - **在宿主工程里测试**(一行接入 `@unif/react-native-design/jest-preset`):
135
+ https://unif-design.github.io/react-native-design/docs/testing
134
136
  - **AI / LLM**(纯 Markdown,按需 fetch,别凭记忆猜 API):
135
137
  [llms.txt 索引](https://unif-design.github.io/react-native-design/llms.txt) · [llms-full.txt 全文](https://unif-design.github.io/react-native-design/llms-full.txt)
136
138
  - **Agent Skill** `design`(`unif` plugin,覆盖组件 API、token 规则、与原生 RN 的关键差异):
package/jest-preset.js ADDED
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * `@unif/react-native-design/jest-preset` —— RN 官方 preset + 本库需要的
5
+ * resolver / transform 放行清单 / setup 接线。消费者:
6
+ *
7
+ * module.exports = { preset: '@unif/react-native-design/jest-preset' };
8
+ *
9
+ * 需要再放行别的包时,spread 本 preset 的 transformIgnorePatterns[0] 后自行追加。
10
+ * 前提:消费者装有 @react-native/jest-preset(RN 应用测试的既有 devDependency)。
11
+ *
12
+ * 注意 package.json#exports 里那条看着重复的 `"./jest-preset/jest-preset"` 别名:
13
+ * jest 解析 `preset` 时只豁免以 `.` 开头(部分版本另豁免绝对路径)的说明符,其余
14
+ * 一律拼上 `/jest-preset`(jest-config normalize.js 的 `PRESET_NAME`)。所以上面那行
15
+ * 文档化用法实际要解析的是 `@unif/react-native-design/jest-preset/jest-preset`。
16
+ * 删掉别名,消费者会直接吃到
17
+ * `Validation Error: Module ... should have "jest-preset.js" or "jest-preset.json" file at the root.`
18
+ *
19
+ * 下面那段 try/catch 就是为了不让「漏装 @react-native/jest-preset」也塌进同一句报错:
20
+ * jest-config 捕获 preset 模块抛出的 MODULE_NOT_FOUND 后,只判 error.message 里有没有
21
+ * preset 路径,而 Node 的 Require stack 恰好带着本文件路径 —— 裸 require 的真因
22
+ * (`Cannot find module '@react-native/jest-preset'`)会被换成上面那句畸形 Validation
23
+ * Error。改抛一个不带 MODULE_NOT_FOUND code 的错误,jest-config 就走
24
+ * `An unknown error occurred in <path>: <message>` 分支,下面这句话原样透出。
25
+ * 于是两个成因彻底分开:漏装有专属报错,Validation Error 只剩别名缺失一个成因。
26
+ */
27
+
28
+ let reactNativePreset;
29
+ try {
30
+ reactNativePreset = require('@react-native/jest-preset');
31
+ } catch (error) {
32
+ if (error && error.code === 'MODULE_NOT_FOUND') {
33
+ throw new Error(
34
+ '@unif/react-native-design/jest-preset 需要宿主工程自行安装 @react-native/jest-preset' +
35
+ '(它不是本包的依赖):yarn add -D @react-native/jest-preset'
36
+ );
37
+ }
38
+ throw error;
39
+ }
40
+
41
+ module.exports = {
42
+ ...reactNativePreset,
43
+ // 组合 resolver:worklets 的 .native.* 过滤 + RN 官方的 exports 剥离,见该文件注释。
44
+ resolver: require.resolve('./jest-resolver.js'),
45
+ setupFilesAfterEnv: [
46
+ ...(reactNativePreset.setupFilesAfterEnv ?? []),
47
+ require.resolve('./jest-setup.js'),
48
+ ],
49
+ // 本库与这些 peer 都发 ESM / TS 源码,RN preset 默认只放行
50
+ // react-native / @react-native / @react-native-community 三个前缀。
51
+ transformIgnorePatterns: [
52
+ 'node_modules/(?!((jest-)?react-native|@react-native(-community)?|@unif/react-native-design|@sbaiahmed1/react-native-blur|react-native-(gesture-handler|reanimated|worklets|safe-area-context|svg|reanimated-carousel))/)',
53
+ ],
54
+ };
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * 组合两个上游 resolver —— 二者缺一都会静默坏掉一类场景:
5
+ *
6
+ * - RN 官方 resolver(`@react-native/jest-preset/jest/resolver.js`,该包无
7
+ * exports 字段,子路径 require 合法):临时剥掉 react-native 的 package
8
+ * exports,jest 才能解析 / mock 其深路径(如消费仓在 mock 的
9
+ * `react-native/Libraries/Utilities/Dimensions`)。
10
+ * - worklets 官方 resolver(`react-native-worklets/jest/resolver`)的语义:
11
+ * 对 worklets 相关请求过滤 .native.* extension,让 jest 走 web 实现,
12
+ * 不触发 native init。
13
+ *
14
+ * jest 的 config `resolver` 是标量,直接写 worklets 的会把 RN 的顶掉,
15
+ * 所以把 worklets 的 extension 过滤内联在这里,再委托给 RN 的 resolver。
16
+ */
17
+
18
+ const reactNativeResolver = require('@react-native/jest-preset/jest/resolver.js');
19
+
20
+ module.exports = (request, options) => {
21
+ if (
22
+ options.basedir.includes('react-native-worklets') ||
23
+ request.includes('react-native-worklets')
24
+ ) {
25
+ options = {
26
+ ...options,
27
+ extensions: options.extensions?.filter((ext) => !ext.includes('native')),
28
+ };
29
+ }
30
+ return reactNativeResolver(request, options);
31
+ };
package/jest-setup.js ADDED
@@ -0,0 +1,49 @@
1
+ /* global jest */
2
+ // ↑ 根 eslint flat config 不给非测试目录注入 jest 全局,显式声明,否则 yarn lint 报 no-undef。
3
+ 'use strict';
4
+
5
+ /**
6
+ * `@unif/react-native-design/jest-setup` —— 把本库 9 个 runtime peer 里在 Jest 中
7
+ * 需要接线的那 4 个接上各自的**官方**桩 / mock / setup。放进消费者的
8
+ * `setupFilesAfterEnv`。(4 个里只有 3 个换了替身,reanimated 走真实模块。)
9
+ *
10
+ * 为什么由库提供:这份接线完全由本库的 peer 集决定,peer range 一变它就得变。
11
+ * 让每个消费仓自己推导的结果是 5 个仓 5 种写法、3 个仓各自踩同一个坑
12
+ * (见 docs/specs/2026-08-05-jest-setup-entry-design.md §1)。
13
+ *
14
+ * `transformIgnorePatterns` 是 resolver 层配置,进不了 setup 文件 —— 那部分在
15
+ * `./jest-preset.js`。
16
+ */
17
+
18
+ // RNGH 官方 jest 桩:让 TurboModuleRegistry.getEnforcing('RNGestureHandlerModule') 不炸。
19
+ require('react-native-gesture-handler/jestSetup');
20
+
21
+ // worklets 的 native 侧在 Jest 里不存在,直接 import 会在 `loadUnpackersWithCode` 处崩。
22
+ jest.mock('react-native-worklets', () =>
23
+ require('react-native-worklets/lib/module/mock')
24
+ );
25
+
26
+ // safe-area 官方 mock:零 inset + 透传 Provider。不接的话 SafeAreaProvider 子树整棵不渲染。
27
+ jest.mock(
28
+ 'react-native-safe-area-context',
29
+ () => require('react-native-safe-area-context/jest/mock').default
30
+ );
31
+
32
+ // RNGH 3 的包根 Pressable 与 GestureDetector 换成不依赖手势的壳。
33
+ // Jest 不触发真实手势,壳不损失可验证行为;保留它们,消费者的用例才不必
34
+ // 每一个都包一层 GestureHandlerRootView(否则 RNGH 3 会抛
35
+ // "GestureDetector must be used as a descendant of GestureHandlerRootView")。
36
+ // 其余导出走真实实现。
37
+ jest.mock('react-native-gesture-handler', () => ({
38
+ ...jest.requireActual('react-native-gesture-handler'),
39
+ Pressable: require('react-native').Pressable,
40
+ GestureDetector: ({ children }) => children,
41
+ }));
42
+
43
+ // reanimated 走**真实模块** + 官方 setUpTests。
44
+ // 不要映射到 `react-native-reanimated/mock`:那是上游刻意残缺的便利 mock
45
+ // (src/mock.ts 里 19 处 `ADD ME IF NEEDED`),缺 useReducedMotion(本库
46
+ // usePrefersReducedMotion 直接调)与 useComposedEventHandler(RNGH 3 Pressable 要用),
47
+ // 且它的 useSharedValue 每次 render 返回新 Proxy,会让把 shared value 放进 effect
48
+ // 依赖数组的组件(本库 ToastHost)在 fake timers 下堆内存耗尽。
49
+ require('react-native-reanimated').setUpTests();
@@ -6,12 +6,12 @@ import { Pressable } from 'react-native-gesture-handler';
6
6
  import { pressedOpacity, r, useColors, useThemedStyles } from "../../../theme/index.js";
7
7
  import { createLogger } from "../../../utils/logger/index.js";
8
8
  import { Icon } from "../Icon/index.js";
9
- import { A11Y_HIDDEN_PROPS } from "../shared/a11y.js";
10
- import { resolveCellActionAccessibilityLabel, resolveCellTitleColor, stringifyCellText } from "./content.js";
9
+ import { A11Y_HIDDEN_PROPS, A11Y_TEXT_ONLY_STYLE } from "../shared/a11y.js";
10
+ import { resolveCellActionAccessibilityLabel, resolveCellTitleColor, resolveExtraSemanticText, stringifyCellText } from "./content.js";
11
11
  import { useListVariant } from "./context.js";
12
12
  import { Leading } from "./Leading.js";
13
13
  import { makeStyles } from "./styles.js";
14
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
15
15
  const log = createLogger('Cell');
16
16
  function CellExtraContent({
17
17
  extra,
@@ -26,10 +26,18 @@ function CellExtraContent({
26
26
  children: stringifyCellText(extra.value)
27
27
  });
28
28
  case 'display':
29
- return /*#__PURE__*/_jsx(View, {
30
- ...A11Y_HIDDEN_PROPS,
31
- children: extra.node
32
- });
29
+ {
30
+ const semantic = resolveExtraSemanticText(extra);
31
+ return /*#__PURE__*/_jsxs(_Fragment, {
32
+ children: [/*#__PURE__*/_jsx(View, {
33
+ ...A11Y_HIDDEN_PROPS,
34
+ children: extra.node
35
+ }), semantic !== undefined ? /*#__PURE__*/_jsx(Text, {
36
+ style: A11Y_TEXT_ONLY_STYLE,
37
+ children: semantic
38
+ }) : null]
39
+ });
40
+ }
33
41
  case 'control':
34
42
  return extra.node;
35
43
  }
@@ -1 +1 @@
1
- {"version":3,"names":["React","useEffect","Text","View","Pressable","pressedOpacity","r","useColors","useThemedStyles","createLogger","Icon","A11Y_HIDDEN_PROPS","resolveCellActionAccessibilityLabel","resolveCellTitleColor","stringifyCellText","useListVariant","Leading","makeStyles","jsx","_jsx","jsxs","_jsxs","log","CellExtraContent","extra","textStyle","kind","style","numberOfLines","children","value","node","Cell","props","c","styles","variant","flush","requestedAction","onPress","accessibilityLabel","title","desc","undefined","hasEffectiveAction","hasMissingActionName","warn","cellStyle","cell","cellFlush","cellFlushWithDesc","titleColor","danger","selected","dangerColor","error","selectedColor","primary","titleStyle","titleFlush","color","descStyle","descFlush","extraStyle","extraFlush","inner","testID","leading","slot","body","titleLines","arrow","chevronFlush","name","size","foregroundSubtle","isDisabled","disabled","accessibilityRole","accessibilityHint","accessibilityState","pressed","opacity","staticLabel","trim","length","accessible"],"sourceRoot":"../../../../../src","sources":["components/ui/Cell/Cell.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","useEffect","Text","View","Pressable","pressedOpacity","r","useColors","useThemedStyles","createLogger","Icon","A11Y_HIDDEN_PROPS","A11Y_TEXT_ONLY_STYLE","resolveCellActionAccessibilityLabel","resolveCellTitleColor","resolveExtraSemanticText","stringifyCellText","useListVariant","Leading","makeStyles","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","log","CellExtraContent","extra","textStyle","kind","style","numberOfLines","children","value","semantic","node","undefined","Cell","props","c","styles","variant","flush","requestedAction","onPress","accessibilityLabel","title","desc","hasEffectiveAction","hasMissingActionName","warn","cellStyle","cell","cellFlush","cellFlushWithDesc","titleColor","danger","selected","dangerColor","error","selectedColor","primary","titleStyle","titleFlush","color","descStyle","descFlush","extraStyle","extraFlush","inner","testID","leading","slot","body","titleLines","arrow","chevronFlush","name","size","foregroundSubtle","isDisabled","disabled","accessibilityRole","accessibilityHint","accessibilityState","pressed","opacity","staticLabel","trim","length","accessible"],"sourceRoot":"../../../../../src","sources":["components/ui/Cell/Cell.tsx"],"mappings":"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","ignoreList":[]}
@@ -47,4 +47,17 @@ export function resolveCellTitleColor({
47
47
  if (selected === true) return selectedColor;
48
48
  return undefined;
49
49
  }
50
+
51
+ /**
52
+ * `extra` 需要额外渲染一份「仅读屏可见」的语义文本吗?
53
+ *
54
+ * 只有 `display` 分支需要:它的视觉节点被 A11Y_HIDDEN_PROPS 移出 a11y 树,
55
+ * 声明的 `accessibilityText` 若不落成真实节点,读屏与按文字查询都拿不到它。
56
+ * `text` 分支本身就是可读文本,`control` 分支由控件自己负责名称。
57
+ */
58
+ export function resolveExtraSemanticText(extra) {
59
+ if (extra?.kind !== 'display') return undefined;
60
+ const text = extra.accessibilityText?.trim();
61
+ return text !== undefined && text.length > 0 ? text : undefined;
62
+ }
50
63
  //# sourceMappingURL=content.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["normalizeNonBlankText","stringifyCellText","value","String","appendNonBlank","parts","normalized","undefined","push","buildCellAccessibilityLabel","title","desc","extra","kind","accessibilityText","join","resolveCellActionAccessibilityLabel","accessibilityLabel","content","resolveCellTitleColor","danger","selected","dangerColor","selectedColor"],"sourceRoot":"../../../../../src","sources":["components/ui/Cell/content.ts"],"mappings":";;AACA,SAASA,qBAAqB,QAAQ,gCAA6B;AAInE,OAAO,SAASC,iBAAiBA,CAACC,KAAoB,EAAU;EAC9D,OAAOC,MAAM,CAACD,KAAK,CAAC;AACtB;AAEA,SAASE,cAAcA,CAACC,KAAe,EAAEH,KAAa,EAAQ;EAC5D,MAAMI,UAAU,GAAGN,qBAAqB,CAACE,KAAK,CAAC;EAC/C,IAAII,UAAU,KAAKC,SAAS,EAAEF,KAAK,CAACG,IAAI,CAACF,UAAU,CAAC;AACtD;AAEA,OAAO,SAASG,2BAA2BA,CAAC;EAC1CC,KAAK;EACLC,IAAI;EACJC;AAKF,CAAC,EAAU;EACT,MAAMP,KAAe,GAAG,EAAE;EAC1BD,cAAc,CAACC,KAAK,EAAEJ,iBAAiB,CAACS,KAAK,CAAC,CAAC;EAE/C,IAAIC,IAAI,KAAKJ,SAAS,EAAE;IACtBH,cAAc,CAACC,KAAK,EAAEJ,iBAAiB,CAACU,IAAI,CAAC,CAAC;EAChD;EAEA,IAAIC,KAAK,EAAEC,IAAI,KAAK,MAAM,EAAE;IAC1BT,cAAc,CAACC,KAAK,EAAEJ,iBAAiB,CAACW,KAAK,CAACV,KAAK,CAAC,CAAC;EACvD,CAAC,MAAM,IAAIU,KAAK,EAAEC,IAAI,KAAK,SAAS,EAAE;IACpCT,cAAc,CAACC,KAAK,EAAEO,KAAK,CAACE,iBAAiB,IAAI,EAAE,CAAC;EACtD;EAEA,OAAOT,KAAK,CAACU,IAAI,CAAC,GAAG,CAAC;AACxB;AAEA,OAAO,SAASC,mCAAmCA,CAAC;EAClDC,kBAAkB;EAClB,GAAGC;AAML,CAAC,EAAsB;EACrB,OACElB,qBAAqB,CAACiB,kBAAkB,CAAC,IACzCjB,qBAAqB,CAACS,2BAA2B,CAACS,OAAO,CAAC,CAAC;AAE/D;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAAC;EACpCC,MAAM;EACNC,QAAQ;EACRC,WAAW;EACXC;AAMF,CAAC,EAAsB;EACrB,IAAIH,MAAM,KAAK,IAAI,EAAE,OAAOE,WAAW;EACvC,IAAID,QAAQ,KAAK,IAAI,EAAE,OAAOE,aAAa;EAC3C,OAAOhB,SAAS;AAClB","ignoreList":[]}
1
+ {"version":3,"names":["normalizeNonBlankText","stringifyCellText","value","String","appendNonBlank","parts","normalized","undefined","push","buildCellAccessibilityLabel","title","desc","extra","kind","accessibilityText","join","resolveCellActionAccessibilityLabel","accessibilityLabel","content","resolveCellTitleColor","danger","selected","dangerColor","selectedColor","resolveExtraSemanticText","text","trim","length"],"sourceRoot":"../../../../../src","sources":["components/ui/Cell/content.ts"],"mappings":";;AACA,SAASA,qBAAqB,QAAQ,gCAA6B;AAInE,OAAO,SAASC,iBAAiBA,CAACC,KAAoB,EAAU;EAC9D,OAAOC,MAAM,CAACD,KAAK,CAAC;AACtB;AAEA,SAASE,cAAcA,CAACC,KAAe,EAAEH,KAAa,EAAQ;EAC5D,MAAMI,UAAU,GAAGN,qBAAqB,CAACE,KAAK,CAAC;EAC/C,IAAII,UAAU,KAAKC,SAAS,EAAEF,KAAK,CAACG,IAAI,CAACF,UAAU,CAAC;AACtD;AAEA,OAAO,SAASG,2BAA2BA,CAAC;EAC1CC,KAAK;EACLC,IAAI;EACJC;AAKF,CAAC,EAAU;EACT,MAAMP,KAAe,GAAG,EAAE;EAC1BD,cAAc,CAACC,KAAK,EAAEJ,iBAAiB,CAACS,KAAK,CAAC,CAAC;EAE/C,IAAIC,IAAI,KAAKJ,SAAS,EAAE;IACtBH,cAAc,CAACC,KAAK,EAAEJ,iBAAiB,CAACU,IAAI,CAAC,CAAC;EAChD;EAEA,IAAIC,KAAK,EAAEC,IAAI,KAAK,MAAM,EAAE;IAC1BT,cAAc,CAACC,KAAK,EAAEJ,iBAAiB,CAACW,KAAK,CAACV,KAAK,CAAC,CAAC;EACvD,CAAC,MAAM,IAAIU,KAAK,EAAEC,IAAI,KAAK,SAAS,EAAE;IACpCT,cAAc,CAACC,KAAK,EAAEO,KAAK,CAACE,iBAAiB,IAAI,EAAE,CAAC;EACtD;EAEA,OAAOT,KAAK,CAACU,IAAI,CAAC,GAAG,CAAC;AACxB;AAEA,OAAO,SAASC,mCAAmCA,CAAC;EAClDC,kBAAkB;EAClB,GAAGC;AAML,CAAC,EAAsB;EACrB,OACElB,qBAAqB,CAACiB,kBAAkB,CAAC,IACzCjB,qBAAqB,CAACS,2BAA2B,CAACS,OAAO,CAAC,CAAC;AAE/D;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAAC;EACpCC,MAAM;EACNC,QAAQ;EACRC,WAAW;EACXC;AAMF,CAAC,EAAsB;EACrB,IAAIH,MAAM,KAAK,IAAI,EAAE,OAAOE,WAAW;EACvC,IAAID,QAAQ,KAAK,IAAI,EAAE,OAAOE,aAAa;EAC3C,OAAOhB,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASiB,wBAAwBA,CACtCZ,KAA4B,EACR;EACpB,IAAIA,KAAK,EAAEC,IAAI,KAAK,SAAS,EAAE,OAAON,SAAS;EAC/C,MAAMkB,IAAI,GAAGb,KAAK,CAACE,iBAAiB,EAAEY,IAAI,CAAC,CAAC;EAC5C,OAAOD,IAAI,KAAKlB,SAAS,IAAIkB,IAAI,CAACE,MAAM,GAAG,CAAC,GAAGF,IAAI,GAAGlB,SAAS;AACjE","ignoreList":[]}
@@ -18,4 +18,21 @@ export const A11Y_HIDDEN_PROPS = {
18
18
  'importantForAccessibility': 'no-hide-descendants',
19
19
  'aria-hidden': true
20
20
  };
21
+
22
+ /**
23
+ * 视觉不可见、但对读屏与测试查询**可达**的文本样式。
24
+ *
25
+ * 用于「视觉由自定义节点承担、语义需要另给一份文字」的场景 —— 典型是 `Cell` 的
26
+ * `extra: { kind: 'display', accessibilityText }`:彩色 Tag 之类的节点本身要从 a11y
27
+ * 树移除(否则读屏逐个念视觉碎片),但它表达的状态必须留下一份可读文本。
28
+ *
29
+ * 不用 `display: 'none'` / `width: 0`:那会让节点连同文本一起从 a11y 树消失,
30
+ * 等于什么都没给。这里是**移出可视区**但保留在树里。
31
+ */
32
+ export const A11Y_TEXT_ONLY_STYLE = {
33
+ position: 'absolute',
34
+ width: 1,
35
+ height: 1,
36
+ opacity: 0
37
+ };
21
38
  //# sourceMappingURL=a11y.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["A11Y_HIDDEN_PROPS"],"sourceRoot":"../../../../../src","sources":["components/ui/shared/a11y.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,iBAAiB,GAAG;EAC/B,YAAY,EAAE,KAAK;EACnB,6BAA6B,EAAE,IAAI;EACnC,2BAA2B,EAAE,qBAAqB;EAClD,aAAa,EAAE;AACjB,CAAU","ignoreList":[]}
1
+ {"version":3,"names":["A11Y_HIDDEN_PROPS","A11Y_TEXT_ONLY_STYLE","position","width","height","opacity"],"sourceRoot":"../../../../../src","sources":["components/ui/shared/a11y.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,iBAAiB,GAAG;EAC/B,YAAY,EAAE,KAAK;EACnB,6BAA6B,EAAE,IAAI;EACnC,2BAA2B,EAAE,qBAAqB;EAClD,aAAa,EAAE;AACjB,CAAU;;AAEV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,oBAAoB,GAAG;EAClCC,QAAQ,EAAE,UAAU;EACpBC,KAAK,EAAE,CAAC;EACRC,MAAM,EAAE,CAAC;EACTC,OAAO,EAAE;AACX,CAAU","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"Cell.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Cell/Cell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAezC,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,SAAS,CAAC;AA0BpD;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAyHxD"}
1
+ {"version":3,"file":"Cell.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Cell/Cell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAgBzC,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,SAAS,CAAC;AAsCpD;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAyHxD"}
@@ -25,5 +25,13 @@ export declare function resolveCellTitleColor({ danger, selected, dangerColor, s
25
25
  dangerColor: string;
26
26
  selectedColor: string;
27
27
  }): string | undefined;
28
+ /**
29
+ * `extra` 需要额外渲染一份「仅读屏可见」的语义文本吗?
30
+ *
31
+ * 只有 `display` 分支需要:它的视觉节点被 A11Y_HIDDEN_PROPS 移出 a11y 树,
32
+ * 声明的 `accessibilityText` 若不落成真实节点,读屏与按文字查询都拿不到它。
33
+ * `text` 分支本身就是可读文本,`control` 分支由控件自己负责名称。
34
+ */
35
+ export declare function resolveExtraSemanticText(extra: CellExtra | undefined): string | undefined;
28
36
  export {};
29
37
  //# sourceMappingURL=content.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Cell/content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxD,KAAK,sBAAsB,GAAG,OAAO,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAEtE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAE9D;AAOD,wBAAgB,2BAA2B,CAAC,EAC1C,KAAK,EACL,IAAI,EACJ,KAAK,GACN,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC,GAAG,MAAM,CAeT;AAED,wBAAgB,mCAAmC,CAAC,EAClD,kBAAkB,EAClB,GAAG,OAAO,EACX,EAAE;IACD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC,GAAG,MAAM,GAAG,SAAS,CAKrB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,QAAQ,EACR,WAAW,EACX,aAAa,GACd,EAAE;IACD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,GAAG,SAAS,CAIrB"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/Cell/content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxD,KAAK,sBAAsB,GAAG,OAAO,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAEtE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAE9D;AAOD,wBAAgB,2BAA2B,CAAC,EAC1C,KAAK,EACL,IAAI,EACJ,KAAK,GACN,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC,GAAG,MAAM,CAeT;AAED,wBAAgB,mCAAmC,CAAC,EAClD,kBAAkB,EAClB,GAAG,OAAO,EACX,EAAE;IACD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC,GAAG,MAAM,GAAG,SAAS,CAKrB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,QAAQ,EACR,WAAW,EACX,aAAa,GACd,EAAE;IACD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,GAAG,SAAS,CAIrB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAIpB"}
@@ -16,4 +16,20 @@ export declare const A11Y_HIDDEN_PROPS: {
16
16
  readonly importantForAccessibility: "no-hide-descendants";
17
17
  readonly 'aria-hidden': true;
18
18
  };
19
+ /**
20
+ * 视觉不可见、但对读屏与测试查询**可达**的文本样式。
21
+ *
22
+ * 用于「视觉由自定义节点承担、语义需要另给一份文字」的场景 —— 典型是 `Cell` 的
23
+ * `extra: { kind: 'display', accessibilityText }`:彩色 Tag 之类的节点本身要从 a11y
24
+ * 树移除(否则读屏逐个念视觉碎片),但它表达的状态必须留下一份可读文本。
25
+ *
26
+ * 不用 `display: 'none'` / `width: 0`:那会让节点连同文本一起从 a11y 树消失,
27
+ * 等于什么都没给。这里是**移出可视区**但保留在树里。
28
+ */
29
+ export declare const A11Y_TEXT_ONLY_STYLE: {
30
+ readonly position: "absolute";
31
+ readonly width: 1;
32
+ readonly height: 1;
33
+ readonly opacity: 0;
34
+ };
19
35
  //# sourceMappingURL=a11y.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/shared/a11y.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB;;;;;CAKpB,CAAC"}
1
+ {"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../../../../../src/components/ui/shared/a11y.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB;;;;;CAKpB,CAAC;AAEX;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB;;;;;CAKvB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unif/react-native-design",
3
- "version": "0.23.0",
3
+ "version": "0.24.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",
@@ -14,12 +14,18 @@
14
14
  "default": "./lib/module/index.js"
15
15
  },
16
16
  "./package.json": "./package.json",
17
+ "./jest-setup": "./jest-setup.js",
18
+ "./jest-preset": "./jest-preset.js",
19
+ "./jest-preset/jest-preset": "./jest-preset.js",
17
20
  "./docs-home.css": "./docs-home.css"
18
21
  },
19
22
  "files": [
20
23
  "src",
21
24
  "lib",
22
25
  "docs-home.css",
26
+ "jest-setup.js",
27
+ "jest-preset.js",
28
+ "jest-resolver.js",
23
29
  "android",
24
30
  "ios",
25
31
  "cpp",
@@ -46,6 +52,7 @@
46
52
  "test": "jest --passWithNoTests",
47
53
  "check:config": "node scripts/check-config.js",
48
54
  "check:icons": "node scripts/check-icons-generated.js",
55
+ "check:jest-entries": "node scripts/check-jest-entries.js",
49
56
  "check:runtime-peers": "node scripts/check-runtime-peers.js",
50
57
  "verify:example-showcase": "node --test scripts/__tests__/verify-example-showcase.test.mjs && node scripts/verify-example-showcase.mjs",
51
58
  "create:runtime-harness": "node scripts/create-runtime-api-harness.js",
@@ -4,10 +4,11 @@ import { Pressable } from 'react-native-gesture-handler';
4
4
  import { pressedOpacity, r, useColors, useThemedStyles } from '../../../theme';
5
5
  import { createLogger } from '../../../utils/logger';
6
6
  import { Icon } from '../Icon';
7
- import { A11Y_HIDDEN_PROPS } from '../shared/a11y';
7
+ import { A11Y_HIDDEN_PROPS, A11Y_TEXT_ONLY_STYLE } from '../shared/a11y';
8
8
  import {
9
9
  resolveCellActionAccessibilityLabel,
10
10
  resolveCellTitleColor,
11
+ resolveExtraSemanticText,
11
12
  stringifyCellText,
12
13
  } from './content';
13
14
  import { useListVariant } from './context';
@@ -32,8 +33,20 @@ function CellExtraContent({
32
33
  {stringifyCellText(extra.value)}
33
34
  </Text>
34
35
  );
35
- case 'display':
36
- return <View {...A11Y_HIDDEN_PROPS}>{extra.node}</View>;
36
+ case 'display': {
37
+ const semantic = resolveExtraSemanticText(extra);
38
+ return (
39
+ <>
40
+ <View {...A11Y_HIDDEN_PROPS}>{extra.node}</View>
41
+ {/* 视觉节点已从 a11y 树移除;accessibilityText 在这里落成一个真实的
42
+ 文本节点,读屏才读得到、测试才按文字查得到。只声明不渲染的话,
43
+ 它对两者都不存在。 */}
44
+ {semantic !== undefined ? (
45
+ <Text style={A11Y_TEXT_ONLY_STYLE}>{semantic}</Text>
46
+ ) : null}
47
+ </>
48
+ );
49
+ }
37
50
  case 'control':
38
51
  return extra.node;
39
52
  }
@@ -72,3 +72,18 @@ export function resolveCellTitleColor({
72
72
  if (selected === true) return selectedColor;
73
73
  return undefined;
74
74
  }
75
+
76
+ /**
77
+ * `extra` 需要额外渲染一份「仅读屏可见」的语义文本吗?
78
+ *
79
+ * 只有 `display` 分支需要:它的视觉节点被 A11Y_HIDDEN_PROPS 移出 a11y 树,
80
+ * 声明的 `accessibilityText` 若不落成真实节点,读屏与按文字查询都拿不到它。
81
+ * `text` 分支本身就是可读文本,`control` 分支由控件自己负责名称。
82
+ */
83
+ export function resolveExtraSemanticText(
84
+ extra: CellExtra | undefined
85
+ ): string | undefined {
86
+ if (extra?.kind !== 'display') return undefined;
87
+ const text = extra.accessibilityText?.trim();
88
+ return text !== undefined && text.length > 0 ? text : undefined;
89
+ }
@@ -16,3 +16,20 @@ export const A11Y_HIDDEN_PROPS = {
16
16
  'importantForAccessibility': 'no-hide-descendants',
17
17
  'aria-hidden': true,
18
18
  } as const;
19
+
20
+ /**
21
+ * 视觉不可见、但对读屏与测试查询**可达**的文本样式。
22
+ *
23
+ * 用于「视觉由自定义节点承担、语义需要另给一份文字」的场景 —— 典型是 `Cell` 的
24
+ * `extra: { kind: 'display', accessibilityText }`:彩色 Tag 之类的节点本身要从 a11y
25
+ * 树移除(否则读屏逐个念视觉碎片),但它表达的状态必须留下一份可读文本。
26
+ *
27
+ * 不用 `display: 'none'` / `width: 0`:那会让节点连同文本一起从 a11y 树消失,
28
+ * 等于什么都没给。这里是**移出可视区**但保留在树里。
29
+ */
30
+ export const A11Y_TEXT_ONLY_STYLE = {
31
+ position: 'absolute',
32
+ width: 1,
33
+ height: 1,
34
+ opacity: 0,
35
+ } as const;