@webority-technologies/mobile-ui 0.0.1 → 0.0.2

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 (134) hide show
  1. package/README.md +2 -1
  2. package/lib/commonjs/components/AuthedImage/AuthedImage.js +225 -0
  3. package/lib/commonjs/components/AuthedImage/authedImageCache.js +253 -0
  4. package/lib/commonjs/components/AuthedImage/index.js +45 -0
  5. package/lib/commonjs/components/BottomSheet/BottomSheet.js +10 -4
  6. package/lib/commonjs/components/Drawer/Drawer.js +6 -3
  7. package/lib/commonjs/components/ErrorBoundary/ErrorBoundary.js +136 -0
  8. package/lib/commonjs/components/ErrorBoundary/index.js +27 -0
  9. package/lib/commonjs/components/ErrorBoundary/useErrorHandler.js +24 -0
  10. package/lib/commonjs/components/ErrorBoundary/withErrorBoundary.js +28 -0
  11. package/lib/commonjs/components/FilePicker/FilePicker.js +1 -1
  12. package/lib/commonjs/components/FloatingActionButton/FloatingActionButton.js +14 -1
  13. package/lib/commonjs/components/ImageGallery/ImageGallery.js +13 -0
  14. package/lib/commonjs/components/InlineSelect/InlineSelect.js +1 -1
  15. package/lib/commonjs/components/Input/Input.js +6 -0
  16. package/lib/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +62 -13
  17. package/lib/commonjs/components/LoaderOverlay/LoaderOverlay.js +203 -0
  18. package/lib/commonjs/components/LoaderOverlay/index.js +25 -0
  19. package/lib/commonjs/components/Markdown/Markdown.js +274 -0
  20. package/lib/commonjs/components/Markdown/index.js +13 -0
  21. package/lib/commonjs/components/Markdown/parse.js +229 -0
  22. package/lib/commonjs/components/OTPInput/OTPInput.js +5 -0
  23. package/lib/commonjs/components/OptionSheet/OptionSheet.js +3 -3
  24. package/lib/commonjs/components/PhoneNumberInput/PhoneNumberInput.js +1 -1
  25. package/lib/commonjs/components/Radio/Radio.js +9 -0
  26. package/lib/commonjs/components/Rating/Rating.js +5 -0
  27. package/lib/commonjs/components/RichTextEditor/RichTextEditor.js +311 -0
  28. package/lib/commonjs/components/RichTextEditor/index.js +20 -0
  29. package/lib/commonjs/components/RichTextEditor/markdownActions.js +213 -0
  30. package/lib/commonjs/components/SearchBar/SearchBar.js +7 -0
  31. package/lib/commonjs/components/Select/Select.js +1 -1
  32. package/lib/commonjs/components/Skeleton/Skeleton.js +17 -36
  33. package/lib/commonjs/components/Slider/Slider.js +21 -5
  34. package/lib/commonjs/components/Swipeable/Swipeable.js +5 -2
  35. package/lib/commonjs/components/TimePicker/TimePicker.js +11 -0
  36. package/lib/commonjs/components/index.js +230 -141
  37. package/lib/commonjs/form/FormContext.js +13 -1
  38. package/lib/commonjs/form/useField.js +13 -1
  39. package/lib/commonjs/theme/Gradient.js +44 -41
  40. package/lib/commonjs/theme/index.js +24 -2
  41. package/lib/commonjs/utils/hapticUtils.js +38 -18
  42. package/lib/module/components/AuthedImage/AuthedImage.js +221 -0
  43. package/lib/module/components/AuthedImage/authedImageCache.js +239 -0
  44. package/lib/module/components/AuthedImage/index.js +5 -0
  45. package/lib/module/components/BottomSheet/BottomSheet.js +10 -4
  46. package/lib/module/components/Drawer/Drawer.js +6 -3
  47. package/lib/module/components/ErrorBoundary/ErrorBoundary.js +130 -0
  48. package/lib/module/components/ErrorBoundary/index.js +6 -0
  49. package/lib/module/components/ErrorBoundary/useErrorHandler.js +20 -0
  50. package/lib/module/components/ErrorBoundary/withErrorBoundary.js +23 -0
  51. package/lib/module/components/FilePicker/FilePicker.js +1 -1
  52. package/lib/module/components/FloatingActionButton/FloatingActionButton.js +14 -1
  53. package/lib/module/components/ImageGallery/ImageGallery.js +13 -0
  54. package/lib/module/components/InlineSelect/InlineSelect.js +1 -1
  55. package/lib/module/components/Input/Input.js +6 -0
  56. package/lib/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.js +63 -14
  57. package/lib/module/components/LoaderOverlay/LoaderOverlay.js +196 -0
  58. package/lib/module/components/LoaderOverlay/index.js +4 -0
  59. package/lib/module/components/Markdown/Markdown.js +268 -0
  60. package/lib/module/components/Markdown/index.js +4 -0
  61. package/lib/module/components/Markdown/parse.js +223 -0
  62. package/lib/module/components/OTPInput/OTPInput.js +5 -0
  63. package/lib/module/components/OptionSheet/OptionSheet.js +3 -3
  64. package/lib/module/components/PhoneNumberInput/PhoneNumberInput.js +1 -1
  65. package/lib/module/components/Radio/Radio.js +9 -0
  66. package/lib/module/components/Rating/Rating.js +5 -0
  67. package/lib/module/components/RichTextEditor/RichTextEditor.js +306 -0
  68. package/lib/module/components/RichTextEditor/index.js +5 -0
  69. package/lib/module/components/RichTextEditor/markdownActions.js +207 -0
  70. package/lib/module/components/SearchBar/SearchBar.js +7 -0
  71. package/lib/module/components/Select/Select.js +1 -1
  72. package/lib/module/components/Skeleton/Skeleton.js +17 -36
  73. package/lib/module/components/Slider/Slider.js +21 -5
  74. package/lib/module/components/Swipeable/Swipeable.js +5 -2
  75. package/lib/module/components/TimePicker/TimePicker.js +11 -0
  76. package/lib/module/components/index.js +5 -0
  77. package/lib/module/form/FormContext.js +13 -1
  78. package/lib/module/form/useField.js +13 -1
  79. package/lib/module/theme/Gradient.js +41 -38
  80. package/lib/module/theme/index.js +17 -1
  81. package/lib/module/utils/hapticUtils.js +37 -18
  82. package/lib/typescript/commonjs/components/AuthedImage/AuthedImage.d.ts +22 -0
  83. package/lib/typescript/commonjs/components/AuthedImage/authedImageCache.d.ts +48 -0
  84. package/lib/typescript/commonjs/components/AuthedImage/index.d.ts +5 -0
  85. package/lib/typescript/commonjs/components/Button/Button.d.ts +1 -3
  86. package/lib/typescript/commonjs/components/Card/Card.d.ts +1 -2
  87. package/lib/typescript/commonjs/components/ErrorBoundary/ErrorBoundary.d.ts +38 -0
  88. package/lib/typescript/commonjs/components/ErrorBoundary/index.d.ts +5 -0
  89. package/lib/typescript/commonjs/components/ErrorBoundary/useErrorHandler.d.ts +9 -0
  90. package/lib/typescript/commonjs/components/ErrorBoundary/withErrorBoundary.d.ts +9 -0
  91. package/lib/typescript/commonjs/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +15 -0
  92. package/lib/typescript/commonjs/components/LoaderOverlay/LoaderOverlay.d.ts +25 -0
  93. package/lib/typescript/commonjs/components/LoaderOverlay/index.d.ts +3 -0
  94. package/lib/typescript/commonjs/components/Markdown/Markdown.d.ts +29 -0
  95. package/lib/typescript/commonjs/components/Markdown/index.d.ts +3 -0
  96. package/lib/typescript/commonjs/components/Markdown/parse.d.ts +58 -0
  97. package/lib/typescript/commonjs/components/OptionSheet/OptionSheet.d.ts +8 -1
  98. package/lib/typescript/commonjs/components/RichTextEditor/RichTextEditor.d.ts +48 -0
  99. package/lib/typescript/commonjs/components/RichTextEditor/index.d.ts +5 -0
  100. package/lib/typescript/commonjs/components/RichTextEditor/markdownActions.d.ts +35 -0
  101. package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +1 -1
  102. package/lib/typescript/commonjs/components/index.d.ts +10 -0
  103. package/lib/typescript/commonjs/form/FormContext.d.ts +13 -3
  104. package/lib/typescript/commonjs/theme/Gradient.d.ts +18 -3
  105. package/lib/typescript/commonjs/theme/index.d.ts +16 -1
  106. package/lib/typescript/commonjs/theme/types.d.ts +2 -2
  107. package/lib/typescript/commonjs/utils/hapticUtils.d.ts +4 -0
  108. package/lib/typescript/module/components/AuthedImage/AuthedImage.d.ts +22 -0
  109. package/lib/typescript/module/components/AuthedImage/authedImageCache.d.ts +48 -0
  110. package/lib/typescript/module/components/AuthedImage/index.d.ts +5 -0
  111. package/lib/typescript/module/components/Button/Button.d.ts +1 -3
  112. package/lib/typescript/module/components/Card/Card.d.ts +1 -2
  113. package/lib/typescript/module/components/ErrorBoundary/ErrorBoundary.d.ts +38 -0
  114. package/lib/typescript/module/components/ErrorBoundary/index.d.ts +5 -0
  115. package/lib/typescript/module/components/ErrorBoundary/useErrorHandler.d.ts +9 -0
  116. package/lib/typescript/module/components/ErrorBoundary/withErrorBoundary.d.ts +9 -0
  117. package/lib/typescript/module/components/KeyboardAwareScrollView/KeyboardAwareScrollView.d.ts +15 -0
  118. package/lib/typescript/module/components/LoaderOverlay/LoaderOverlay.d.ts +25 -0
  119. package/lib/typescript/module/components/LoaderOverlay/index.d.ts +3 -0
  120. package/lib/typescript/module/components/Markdown/Markdown.d.ts +29 -0
  121. package/lib/typescript/module/components/Markdown/index.d.ts +3 -0
  122. package/lib/typescript/module/components/Markdown/parse.d.ts +58 -0
  123. package/lib/typescript/module/components/OptionSheet/OptionSheet.d.ts +8 -1
  124. package/lib/typescript/module/components/RichTextEditor/RichTextEditor.d.ts +48 -0
  125. package/lib/typescript/module/components/RichTextEditor/index.d.ts +5 -0
  126. package/lib/typescript/module/components/RichTextEditor/markdownActions.d.ts +35 -0
  127. package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +1 -1
  128. package/lib/typescript/module/components/index.d.ts +10 -0
  129. package/lib/typescript/module/form/FormContext.d.ts +13 -3
  130. package/lib/typescript/module/theme/Gradient.d.ts +18 -3
  131. package/lib/typescript/module/theme/index.d.ts +16 -1
  132. package/lib/typescript/module/theme/types.d.ts +2 -2
  133. package/lib/typescript/module/utils/hapticUtils.d.ts +4 -0
  134. package/package.json +20 -13
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Markdown = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _index = require("../../theme/index.js");
10
+ var _index2 = require("../Skeleton/index.js");
11
+ var _parse = require("./parse.js");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
+ const renderInline = (nodes, theme, onLinkPress, keyPrefix = 'i') => nodes.map((node, index) => {
15
+ const key = `${keyPrefix}-${index}`;
16
+ switch (node.type) {
17
+ case 'text':
18
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
19
+ children: node.value
20
+ }, key);
21
+ case 'strong':
22
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
23
+ style: {
24
+ fontWeight: theme.typography.fontWeight.bold
25
+ },
26
+ children: renderInline(node.children, theme, onLinkPress, key)
27
+ }, key);
28
+ case 'em':
29
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
30
+ style: {
31
+ fontStyle: 'italic'
32
+ },
33
+ children: renderInline(node.children, theme, onLinkPress, key)
34
+ }, key);
35
+ case 'strike':
36
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
37
+ style: {
38
+ textDecorationLine: 'line-through'
39
+ },
40
+ children: renderInline(node.children, theme, onLinkPress, key)
41
+ }, key);
42
+ case 'code':
43
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
44
+ style: {
45
+ fontFamily: MONO,
46
+ backgroundColor: theme.colors.background.secondary,
47
+ color: theme.colors.text.primary
48
+ },
49
+ children: node.value
50
+ }, key);
51
+ case 'link':
52
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
53
+ accessibilityRole: "link",
54
+ onPress: () => onLinkPress(node.href),
55
+ style: {
56
+ color: theme.colors.text.link,
57
+ textDecorationLine: 'underline'
58
+ },
59
+ children: renderInline(node.children, theme, onLinkPress, key)
60
+ }, key);
61
+ default:
62
+ return null;
63
+ }
64
+ });
65
+
66
+ /** The theme carries no monospace family, and code has to look like code. */
67
+ const MONO = _reactNative.Platform.select({
68
+ ios: 'Menlo',
69
+ android: 'monospace',
70
+ default: 'monospace'
71
+ });
72
+
73
+ /** The theme's scale is xs/sm/base/lg/xl/2xl/3xl/4xl — no md, no xxl. */
74
+ const HEADING_SCALE = {
75
+ 1: '3xl',
76
+ 2: '2xl',
77
+ 3: 'xl',
78
+ 4: 'lg',
79
+ 5: 'base',
80
+ 6: 'sm'
81
+ };
82
+
83
+ /**
84
+ * Renders a small, deliberate subset of markdown using the theme's own type
85
+ * scale and colours, with no dependency.
86
+ *
87
+ * It exists because Expo has no markdown module and the alternative on npm has
88
+ * not shipped since 2022. What it covers is what our content contains: release
89
+ * notes, help text and descriptions written by people. Nested lists, tables and
90
+ * inline HTML are out of scope on purpose — see parse.ts.
91
+ */
92
+ const Markdown = ({
93
+ children,
94
+ onLinkPress,
95
+ loading = false,
96
+ style,
97
+ textStyle,
98
+ testID
99
+ }) => {
100
+ const theme = (0, _index.useTheme)();
101
+ const styles = (0, _react.useMemo)(() => createStyles(theme), [theme]);
102
+ const blocks = (0, _react.useMemo)(() => (0, _parse.parseMarkdown)(children ?? ''), [children]);
103
+ const handleLink = href => {
104
+ if (onLinkPress) {
105
+ onLinkPress(href);
106
+ return;
107
+ }
108
+ // Rejections are swallowed: a link the OS cannot open is not a crash, and
109
+ // there is no useful recovery from inside a text run.
110
+ void _reactNative.Linking.openURL(href).catch(() => undefined);
111
+ };
112
+ if (loading) {
113
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(MarkdownSkeleton, {
114
+ style: style,
115
+ testID: testID
116
+ });
117
+ }
118
+ if (blocks.length === 0) {
119
+ return null;
120
+ }
121
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
122
+ style: style,
123
+ testID: testID,
124
+ children: blocks.map((block, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(MarkdownBlock, {
125
+ block: block,
126
+ theme: theme,
127
+ styles: styles,
128
+ textStyle: textStyle,
129
+ onLinkPress: handleLink
130
+ }, `b-${index}`))
131
+ });
132
+ };
133
+ exports.Markdown = Markdown;
134
+ Markdown.displayName = 'Markdown';
135
+ const MarkdownBlock = ({
136
+ block,
137
+ theme,
138
+ styles,
139
+ textStyle,
140
+ onLinkPress
141
+ }) => {
142
+ switch (block.type) {
143
+ case 'heading':
144
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
145
+ accessibilityRole: "header",
146
+ style: [styles.block, {
147
+ fontSize: theme.typography.fontSize[HEADING_SCALE[block.level]],
148
+ fontWeight: theme.typography.fontWeight.semibold,
149
+ color: theme.colors.text.primary
150
+ }, textStyle],
151
+ children: renderInline(block.children, theme, onLinkPress)
152
+ });
153
+ case 'paragraph':
154
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
155
+ style: [styles.block, styles.body, textStyle],
156
+ children: renderInline(block.children, theme, onLinkPress)
157
+ });
158
+ case 'listItem':
159
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
160
+ style: [styles.listRow, {
161
+ marginLeft: block.depth * theme.spacing.md
162
+ }],
163
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
164
+ style: [styles.body, styles.bullet, textStyle],
165
+ children: block.ordered ? `${block.index}.` : '•'
166
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
167
+ style: [styles.body, styles.listText, textStyle],
168
+ children: renderInline(block.children, theme, onLinkPress)
169
+ })]
170
+ });
171
+ case 'quote':
172
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
173
+ style: styles.quote,
174
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
175
+ style: [styles.body, styles.quoteText, textStyle],
176
+ children: renderInline(block.children, theme, onLinkPress)
177
+ })
178
+ });
179
+ case 'codeBlock':
180
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
181
+ style: styles.codeBlock,
182
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
183
+ style: styles.codeText,
184
+ children: block.value
185
+ })
186
+ });
187
+ case 'rule':
188
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
189
+ style: styles.rule
190
+ });
191
+ default:
192
+ return null;
193
+ }
194
+ };
195
+ const MarkdownSkeleton = ({
196
+ style,
197
+ testID
198
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
199
+ style: style,
200
+ testID: testID,
201
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Skeleton, {
202
+ shape: "text",
203
+ width: "70%",
204
+ height: 20,
205
+ style: {
206
+ marginBottom: 8
207
+ }
208
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Skeleton, {
209
+ shape: "text",
210
+ width: "100%",
211
+ height: 14,
212
+ style: {
213
+ marginBottom: 6
214
+ }
215
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Skeleton, {
216
+ shape: "text",
217
+ width: "92%",
218
+ height: 14,
219
+ style: {
220
+ marginBottom: 6
221
+ }
222
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Skeleton, {
223
+ shape: "text",
224
+ width: "60%",
225
+ height: 14
226
+ })]
227
+ });
228
+ const createStyles = theme => _reactNative.StyleSheet.create({
229
+ block: {
230
+ marginBottom: theme.spacing.sm
231
+ },
232
+ body: {
233
+ fontSize: theme.typography.fontSize.base,
234
+ color: theme.colors.text.primary,
235
+ lineHeight: theme.typography.fontSize.base * 1.5
236
+ },
237
+ listRow: {
238
+ flexDirection: 'row',
239
+ marginBottom: theme.spacing.xs
240
+ },
241
+ bullet: {
242
+ width: theme.spacing.lg
243
+ },
244
+ listText: {
245
+ flex: 1
246
+ },
247
+ quote: {
248
+ borderLeftWidth: 3,
249
+ borderLeftColor: theme.colors.border.secondary,
250
+ paddingLeft: theme.spacing.sm,
251
+ marginBottom: theme.spacing.sm
252
+ },
253
+ quoteText: {
254
+ color: theme.colors.text.secondary,
255
+ fontStyle: 'italic'
256
+ },
257
+ codeBlock: {
258
+ backgroundColor: theme.colors.background.secondary,
259
+ borderRadius: theme.radius.sm,
260
+ padding: theme.spacing.sm,
261
+ marginBottom: theme.spacing.sm
262
+ },
263
+ codeText: {
264
+ fontFamily: MONO,
265
+ fontSize: theme.typography.fontSize.sm,
266
+ color: theme.colors.text.primary
267
+ },
268
+ rule: {
269
+ height: _reactNative.StyleSheet.hairlineWidth,
270
+ backgroundColor: theme.colors.border.primary,
271
+ marginVertical: theme.spacing.md
272
+ }
273
+ });
274
+ //# sourceMappingURL=Markdown.js.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "Markdown", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _Markdown.Markdown;
10
+ }
11
+ });
12
+ var _Markdown = require("./Markdown.js");
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseMarkdown = exports.parseInline = void 0;
7
+ /**
8
+ * A deliberately small CommonMark subset, parsed without a dependency.
9
+ *
10
+ * The scope is what our own content actually contains — release notes, help
11
+ * text, descriptions written by people in a web editor — not a spec-complete
12
+ * renderer. Nested lists, tables, footnotes, HTML blocks and reference links
13
+ * are out of scope on purpose: supporting them means a parser nobody here can
14
+ * maintain, and content that needs them is a sign it should not be markdown.
15
+ *
16
+ * Kept separate from the component so the grammar can be tested as data, with
17
+ * no rendering involved.
18
+ */
19
+
20
+ /**
21
+ * Inline parsing is a single left-to-right scan rather than nested regex
22
+ * replacement: replacement cannot express "a `code` span suppresses every other
23
+ * marker inside it", which is the one rule that makes documentation readable.
24
+ */
25
+ const INLINE_PATTERNS = [
26
+ // Code first: everything inside a span is literal.
27
+ {
28
+ re: /^`([^`]+)`/,
29
+ build: m => ({
30
+ type: 'code',
31
+ value: m[1]
32
+ })
33
+ }, {
34
+ re: /^\[([^\]]*)\]\(([^)\s]+)\)/,
35
+ build: (m, parse) => ({
36
+ type: 'link',
37
+ href: m[2],
38
+ children: parse(m[1])
39
+ })
40
+ },
41
+ // Non-greedy across ANY character, not "everything except the delimiter":
42
+ // the excluding form cannot match `**bold with *italic* inside**`, because
43
+ // the content legitimately contains the single-character marker. `**` is
44
+ // listed before `*` so the longer delimiter always wins.
45
+ {
46
+ re: /^\*\*([\s\S]+?)\*\*/,
47
+ build: (m, parse) => ({
48
+ type: 'strong',
49
+ children: parse(m[1])
50
+ })
51
+ }, {
52
+ re: /^__([\s\S]+?)__/,
53
+ build: (m, parse) => ({
54
+ type: 'strong',
55
+ children: parse(m[1])
56
+ })
57
+ }, {
58
+ re: /^~~([\s\S]+?)~~/,
59
+ build: (m, parse) => ({
60
+ type: 'strike',
61
+ children: parse(m[1])
62
+ })
63
+ }, {
64
+ re: /^\*([^*\n]+)\*/,
65
+ build: (m, parse) => ({
66
+ type: 'em',
67
+ children: parse(m[1])
68
+ })
69
+ }, {
70
+ re: /^_([^_\n]+)_/,
71
+ build: (m, parse) => ({
72
+ type: 'em',
73
+ children: parse(m[1])
74
+ })
75
+ }];
76
+ const parseInline = input => {
77
+ const out = [];
78
+ let buffer = '';
79
+ let rest = input;
80
+ const flush = () => {
81
+ if (buffer) {
82
+ out.push({
83
+ type: 'text',
84
+ value: buffer
85
+ });
86
+ buffer = '';
87
+ }
88
+ };
89
+ while (rest.length > 0) {
90
+ // A backslash escapes the next character, so a literal asterisk is writable.
91
+ if (rest.startsWith('\\') && rest.length > 1) {
92
+ buffer += rest[1];
93
+ rest = rest.slice(2);
94
+ continue;
95
+ }
96
+ let matched = false;
97
+ for (const {
98
+ re,
99
+ build
100
+ } of INLINE_PATTERNS) {
101
+ const m = re.exec(rest);
102
+ if (m) {
103
+ flush();
104
+ out.push(build(m, parseInline));
105
+ rest = rest.slice(m[0].length);
106
+ matched = true;
107
+ break;
108
+ }
109
+ }
110
+ if (!matched) {
111
+ buffer += rest[0];
112
+ rest = rest.slice(1);
113
+ }
114
+ }
115
+ flush();
116
+ return out;
117
+ };
118
+
119
+ /**
120
+ * Indent to nesting depth. Two spaces per level is the CommonMark-ish
121
+ * convention people actually type; a tab counts as one level. Depth is capped
122
+ * because the renderer indents by depth and a runaway indent would push the
123
+ * text off screen rather than fail visibly.
124
+ */
125
+ exports.parseInline = parseInline;
126
+ const MAX_LIST_DEPTH = 4;
127
+ const depthOf = indent => {
128
+ const spaces = indent.replace(/\t/g, ' ').length;
129
+ return Math.min(Math.floor(spaces / 2), MAX_LIST_DEPTH);
130
+ };
131
+ const HEADING = /^(#{1,6})\s+(.*)$/;
132
+ const UNORDERED = /^(\s*)[-*+]\s+(.*)$/;
133
+ const ORDERED = /^(\s*)(\d+)[.)]\s+(.*)$/;
134
+ const QUOTE = /^\s*>\s?(.*)$/;
135
+ const RULE = /^\s*([-*_])\s*(?:\1\s*){2,}$/;
136
+ const FENCE = /^\s*```\s*(\S+)?\s*$/;
137
+ const parseMarkdown = source => {
138
+ const blocks = [];
139
+ const lines = (source ?? '').replace(/\r\n?/g, '\n').split('\n');
140
+ let paragraph = [];
141
+ const flushParagraph = () => {
142
+ if (paragraph.length > 0) {
143
+ blocks.push({
144
+ type: 'paragraph',
145
+ children: parseInline(paragraph.join(' ').trim())
146
+ });
147
+ paragraph = [];
148
+ }
149
+ };
150
+ for (let i = 0; i < lines.length; i++) {
151
+ const line = lines[i];
152
+ const fence = FENCE.exec(line);
153
+ if (fence) {
154
+ flushParagraph();
155
+ const body = [];
156
+ i++;
157
+ while (i < lines.length && !FENCE.test(lines[i])) {
158
+ body.push(lines[i]);
159
+ i++;
160
+ }
161
+ blocks.push({
162
+ type: 'codeBlock',
163
+ value: body.join('\n'),
164
+ language: fence[1]
165
+ });
166
+ continue;
167
+ }
168
+ if (line.trim() === '') {
169
+ flushParagraph();
170
+ continue;
171
+ }
172
+ // Checked before the list patterns: `---` is also a valid bullet to them.
173
+ if (RULE.test(line)) {
174
+ flushParagraph();
175
+ blocks.push({
176
+ type: 'rule'
177
+ });
178
+ continue;
179
+ }
180
+ const heading = HEADING.exec(line);
181
+ if (heading) {
182
+ flushParagraph();
183
+ blocks.push({
184
+ type: 'heading',
185
+ level: heading[1].length,
186
+ children: parseInline(heading[2])
187
+ });
188
+ continue;
189
+ }
190
+ const ordered = ORDERED.exec(line);
191
+ if (ordered) {
192
+ flushParagraph();
193
+ blocks.push({
194
+ type: 'listItem',
195
+ ordered: true,
196
+ index: Number(ordered[2]),
197
+ depth: depthOf(ordered[1]),
198
+ children: parseInline(ordered[3])
199
+ });
200
+ continue;
201
+ }
202
+ const unordered = UNORDERED.exec(line);
203
+ if (unordered) {
204
+ flushParagraph();
205
+ blocks.push({
206
+ type: 'listItem',
207
+ ordered: false,
208
+ index: 0,
209
+ depth: depthOf(unordered[1]),
210
+ children: parseInline(unordered[2])
211
+ });
212
+ continue;
213
+ }
214
+ const quote = QUOTE.exec(line);
215
+ if (quote) {
216
+ flushParagraph();
217
+ blocks.push({
218
+ type: 'quote',
219
+ children: parseInline(quote[1])
220
+ });
221
+ continue;
222
+ }
223
+ paragraph.push(line.trim());
224
+ }
225
+ flushParagraph();
226
+ return blocks;
227
+ };
228
+ exports.parseMarkdown = parseMarkdown;
229
+ //# sourceMappingURL=parse.js.map
@@ -148,6 +148,11 @@ const OTPInput = exports.OTPInput = /*#__PURE__*/(0, _react.forwardRef)((props,
148
148
  if (previous === focusedIndex) {
149
149
  return;
150
150
  }
151
+ // Equivalent-mutant note: this branch is unreachable, so removing it
152
+ // cannot change behaviour. Reaching here already proves
153
+ // `previous !== focusedIndex` (the check above returned otherwise), so
154
+ // `previous === -1 && focusedIndex === -1` — which requires them equal —
155
+ // can never be true.
151
156
  if (previous === -1 && focusedIndex === -1) {
152
157
  return;
153
158
  }
@@ -36,7 +36,7 @@ const OptionSheet = props => {
36
36
  title,
37
37
  options,
38
38
  labelOf,
39
- valueOf,
39
+ getValue,
40
40
  disabledOf,
41
41
  descriptionOf,
42
42
  iconOf,
@@ -178,7 +178,7 @@ const OptionSheet = props => {
178
178
  item
179
179
  }) => {
180
180
  const itemLabel = labelOf(item);
181
- const itemValue = valueOf(item);
181
+ const itemValue = getValue(item);
182
182
  const itemDescription = descriptionOf(item);
183
183
  const itemIcon = iconOf(item);
184
184
  const selected = isSelected(itemValue);
@@ -316,7 +316,7 @@ const OptionSheet = props => {
316
316
  })
317
317
  }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
318
318
  data: filteredOptions,
319
- keyExtractor: item => String(valueOf(item)),
319
+ keyExtractor: item => String(getValue(item)),
320
320
  renderItem: renderOption,
321
321
  keyboardShouldPersistTaps: "handled",
322
322
  showsVerticalScrollIndicator: true,
@@ -208,7 +208,7 @@ const PhoneNumberInput = exports.PhoneNumberInput = /*#__PURE__*/(0, _react.forw
208
208
  title: countrySheetTitle,
209
209
  options: countries,
210
210
  labelOf: o => `${o.label} (+${o.code})`,
211
- valueOf: o => o.iso,
211
+ getValue: o => o.iso,
212
212
  disabledOf: () => false,
213
213
  descriptionOf: () => undefined,
214
214
  iconOf: () => null,
@@ -48,6 +48,15 @@ const Radio = exports.Radio = /*#__PURE__*/(0, _react.forwardRef)((props, ref) =
48
48
  const theme = (0, _index.useTheme)();
49
49
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
50
50
  const ctx = useRadioGroup();
51
+
52
+ // `value` is required by the props, but a JavaScript consumer can still omit
53
+ // it, and the failure is silent rather than loud: inside a group,
54
+ // `selectedValue === undefined` makes every unselected radio look selected the
55
+ // moment nothing is chosen, and pressing one reports `undefined` as the
56
+ // choice. A conformance test omitted it for months without anything noticing.
57
+ if (__DEV__ && value === undefined) {
58
+ console.warn('[@webority-technologies/mobile-ui] Radio was rendered without a `value`. ' + 'Selection compares against it, so the group cannot track which option is chosen.');
59
+ }
51
60
  const selected = ctx ? ctx.selectedValue === value : !!selectedProp;
52
61
  const disabled = ctx ? ctx.disabled || disabledProp : disabledProp;
53
62
  const fillColor = toneColor(theme, tone);
@@ -126,6 +126,11 @@ const Rating = exports.Rating = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
126
126
  const pulseScale = theme.components.rating?.pulseScale ?? 1.2;
127
127
  const pulse = (0, _react.useCallback)(idx => {
128
128
  const v = scaleRefs[idx];
129
+ // Equivalent mutant, not an untested guard: `pulse` is only ever invoked from
130
+ // `commit` with an `animatedIndex` sourced from the star-loop below, which
131
+ // only pushes indices already confirmed present in `scaleRefs` (same render,
132
+ // same `max`). `v` is therefore always defined here — no reachable input
133
+ // makes this `return` fire, so no test can kill its removal.
129
134
  if (!v) {
130
135
  return;
131
136
  }