@agimon-ai/po-native-components 0.0.0-alpha.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 (122) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +71 -0
  3. package/dist/components/Badge.d.mts +17 -0
  4. package/dist/components/Badge.d.mts.map +1 -0
  5. package/dist/components/Badge.mjs +106 -0
  6. package/dist/components/Badge.mjs.map +1 -0
  7. package/dist/components/Button.d.mts +20 -0
  8. package/dist/components/Button.d.mts.map +1 -0
  9. package/dist/components/Button.mjs +278 -0
  10. package/dist/components/Button.mjs.map +1 -0
  11. package/dist/components/CodeBlock.d.mts +10 -0
  12. package/dist/components/CodeBlock.d.mts.map +1 -0
  13. package/dist/components/CodeBlock.mjs +88 -0
  14. package/dist/components/CodeBlock.mjs.map +1 -0
  15. package/dist/components/Dialog.d.mts +52 -0
  16. package/dist/components/Dialog.d.mts.map +1 -0
  17. package/dist/components/Dialog.mjs +257 -0
  18. package/dist/components/Dialog.mjs.map +1 -0
  19. package/dist/components/Dot.d.mts +17 -0
  20. package/dist/components/Dot.d.mts.map +1 -0
  21. package/dist/components/Dot.mjs +94 -0
  22. package/dist/components/Dot.mjs.map +1 -0
  23. package/dist/components/DropdownMenu.d.mts +63 -0
  24. package/dist/components/DropdownMenu.d.mts.map +1 -0
  25. package/dist/components/DropdownMenu.mjs +256 -0
  26. package/dist/components/DropdownMenu.mjs.map +1 -0
  27. package/dist/components/EmptyState.d.mts +14 -0
  28. package/dist/components/EmptyState.d.mts.map +1 -0
  29. package/dist/components/EmptyState.mjs +64 -0
  30. package/dist/components/EmptyState.mjs.map +1 -0
  31. package/dist/components/Input.d.mts +19 -0
  32. package/dist/components/Input.d.mts.map +1 -0
  33. package/dist/components/Input.mjs +123 -0
  34. package/dist/components/Input.mjs.map +1 -0
  35. package/dist/components/Label.d.mts +13 -0
  36. package/dist/components/Label.d.mts.map +1 -0
  37. package/dist/components/Label.mjs +36 -0
  38. package/dist/components/Label.mjs.map +1 -0
  39. package/dist/components/List.d.mts +48 -0
  40. package/dist/components/List.d.mts.map +1 -0
  41. package/dist/components/List.mjs +156 -0
  42. package/dist/components/List.mjs.map +1 -0
  43. package/dist/components/Markdown.d.mts +15 -0
  44. package/dist/components/Markdown.d.mts.map +1 -0
  45. package/dist/components/Markdown.mjs +219 -0
  46. package/dist/components/Markdown.mjs.map +1 -0
  47. package/dist/components/MessageItem.d.mts +87 -0
  48. package/dist/components/MessageItem.d.mts.map +1 -0
  49. package/dist/components/MessageItem.mjs +361 -0
  50. package/dist/components/MessageItem.mjs.map +1 -0
  51. package/dist/components/Panel.d.mts +15 -0
  52. package/dist/components/Panel.d.mts.map +1 -0
  53. package/dist/components/Panel.mjs +77 -0
  54. package/dist/components/Panel.mjs.map +1 -0
  55. package/dist/components/PoNativeProvider.d.mts +15 -0
  56. package/dist/components/PoNativeProvider.d.mts.map +1 -0
  57. package/dist/components/PoNativeProvider.mjs +22 -0
  58. package/dist/components/PoNativeProvider.mjs.map +1 -0
  59. package/dist/components/SectionLabel.d.mts +6 -0
  60. package/dist/components/SectionLabel.d.mts.map +1 -0
  61. package/dist/components/SectionLabel.mjs +40 -0
  62. package/dist/components/SectionLabel.mjs.map +1 -0
  63. package/dist/components/SegmentedControl.d.mts +26 -0
  64. package/dist/components/SegmentedControl.d.mts.map +1 -0
  65. package/dist/components/SegmentedControl.mjs +56 -0
  66. package/dist/components/SegmentedControl.mjs.map +1 -0
  67. package/dist/components/Sheet.d.mts +39 -0
  68. package/dist/components/Sheet.d.mts.map +1 -0
  69. package/dist/components/Sheet.mjs +166 -0
  70. package/dist/components/Sheet.mjs.map +1 -0
  71. package/dist/components/SheetFrame.mjs +84 -0
  72. package/dist/components/SheetFrame.mjs.map +1 -0
  73. package/dist/components/Spinner.d.mts +19 -0
  74. package/dist/components/Spinner.d.mts.map +1 -0
  75. package/dist/components/Spinner.mjs +34 -0
  76. package/dist/components/Spinner.mjs.map +1 -0
  77. package/dist/components/StatusBadge.d.mts +23 -0
  78. package/dist/components/StatusBadge.d.mts.map +1 -0
  79. package/dist/components/StatusBadge.mjs +116 -0
  80. package/dist/components/StatusBadge.mjs.map +1 -0
  81. package/dist/components/Tabs.d.mts +44 -0
  82. package/dist/components/Tabs.d.mts.map +1 -0
  83. package/dist/components/Tabs.mjs +197 -0
  84. package/dist/components/Tabs.mjs.map +1 -0
  85. package/dist/components/Textarea.d.mts +10 -0
  86. package/dist/components/Textarea.d.mts.map +1 -0
  87. package/dist/components/Textarea.mjs +29 -0
  88. package/dist/components/Textarea.mjs.map +1 -0
  89. package/dist/icons/IconColorContext.d.mts +10 -0
  90. package/dist/icons/IconColorContext.d.mts.map +1 -0
  91. package/dist/icons/IconColorContext.mjs +13 -0
  92. package/dist/icons/IconColorContext.mjs.map +1 -0
  93. package/dist/icons/iconGlyphs.d.mts +120 -0
  94. package/dist/icons/iconGlyphs.d.mts.map +1 -0
  95. package/dist/icons/iconGlyphs.mjs +121 -0
  96. package/dist/icons/iconGlyphs.mjs.map +1 -0
  97. package/dist/icons/icons.d.mts +122 -0
  98. package/dist/icons/icons.d.mts.map +1 -0
  99. package/dist/icons/icons.mjs +79 -0
  100. package/dist/icons/icons.mjs.map +1 -0
  101. package/dist/index.d.mts +27 -0
  102. package/dist/index.mjs +27 -0
  103. package/dist/lib/fonts.d.mts +13 -0
  104. package/dist/lib/fonts.d.mts.map +1 -0
  105. package/dist/lib/fonts.mjs +22 -0
  106. package/dist/lib/fonts.mjs.map +1 -0
  107. package/dist/lib/haptics.d.mts +7 -0
  108. package/dist/lib/haptics.d.mts.map +1 -0
  109. package/dist/lib/haptics.mjs +25 -0
  110. package/dist/lib/haptics.mjs.map +1 -0
  111. package/dist/lib/insideSheet.mjs +16 -0
  112. package/dist/lib/insideSheet.mjs.map +1 -0
  113. package/dist/lib/markdown.mjs +271 -0
  114. package/dist/lib/markdown.mjs.map +1 -0
  115. package/dist/lib/tone.mjs +50 -0
  116. package/dist/lib/tone.mjs.map +1 -0
  117. package/dist/lib/useControllable.mjs +22 -0
  118. package/dist/lib/useControllable.mjs.map +1 -0
  119. package/dist/lib/wrapText.mjs +20 -0
  120. package/dist/lib/wrapText.mjs.map +1 -0
  121. package/llms.txt +8 -0
  122. package/package.json +104 -0
@@ -0,0 +1,271 @@
1
+ //#region src/lib/markdown.ts
2
+ const FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})[ \t]*([^\s`]*)/;
3
+ const HEADING = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/;
4
+ const RULE = /^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/;
5
+ const BULLET_ITEM = /^ {0,3}[-*+][ \t]+(.*)$/;
6
+ const ORDERED_ITEM = /^ {0,3}(\d{1,9})[.)][ \t]+(.*)$/;
7
+ const INDENTED = /^[ \t]+\S/;
8
+ const ESCAPABLE = /[!-/:-@[-`{-~]/;
9
+ const WORD_CHAR = /[\p{L}\p{N}]/u;
10
+ function isBlank(line) {
11
+ return line.trim() === "";
12
+ }
13
+ /** Parses a Markdown document into blocks. */
14
+ function parseMarkdown(source) {
15
+ const lines = source.replace(/\r\n?/g, "\n").split("\n");
16
+ const blocks = [];
17
+ let paragraph = [];
18
+ let list;
19
+ const flushParagraph = () => {
20
+ if (paragraph.length > 0) blocks.push({
21
+ type: "paragraph",
22
+ children: parseInline(paragraph.join("\n"))
23
+ });
24
+ paragraph = [];
25
+ };
26
+ const flushList = () => {
27
+ if (list !== void 0) blocks.push({
28
+ type: "list",
29
+ ordered: list.ordered,
30
+ start: list.start,
31
+ items: list.items.map(parseInline)
32
+ });
33
+ list = void 0;
34
+ };
35
+ const flush = () => {
36
+ flushParagraph();
37
+ flushList();
38
+ };
39
+ for (let index = 0; index < lines.length; index += 1) {
40
+ const line = lines[index];
41
+ const fence = FENCE_OPEN.exec(line);
42
+ if (fence !== null) {
43
+ flush();
44
+ const marker = fence[1];
45
+ const close = new RegExp(`^ {0,3}${marker[0] === "`" ? "`" : "~"}{${marker.length},}[ \\t]*$`);
46
+ const body = [];
47
+ index += 1;
48
+ while (index < lines.length && !close.test(lines[index])) {
49
+ body.push(lines[index]);
50
+ index += 1;
51
+ }
52
+ const language = fence[2] === void 0 || fence[2] === "" ? void 0 : fence[2];
53
+ blocks.push({
54
+ type: "code",
55
+ language,
56
+ text: body.join("\n")
57
+ });
58
+ continue;
59
+ }
60
+ if (isBlank(line)) {
61
+ flush();
62
+ continue;
63
+ }
64
+ const heading = HEADING.exec(line);
65
+ if (heading !== null) {
66
+ flush();
67
+ const level = heading[1].length;
68
+ blocks.push({
69
+ type: "heading",
70
+ level,
71
+ children: parseInline(heading[2] ?? "")
72
+ });
73
+ continue;
74
+ }
75
+ if (RULE.test(line)) {
76
+ flush();
77
+ blocks.push({ type: "rule" });
78
+ continue;
79
+ }
80
+ const bullet = BULLET_ITEM.exec(line);
81
+ const ordered = bullet === null ? ORDERED_ITEM.exec(line) : null;
82
+ if (bullet !== null || ordered !== null) {
83
+ flushParagraph();
84
+ const isOrdered = ordered !== null;
85
+ if (list === void 0 || list.ordered !== isOrdered) {
86
+ flushList();
87
+ list = {
88
+ ordered: isOrdered,
89
+ start: isOrdered ? Number(ordered[1]) : 1,
90
+ items: []
91
+ };
92
+ }
93
+ list.items.push(isOrdered ? ordered[2] : bullet[1]);
94
+ continue;
95
+ }
96
+ if (list !== void 0 && INDENTED.test(line)) {
97
+ const last = list.items.length - 1;
98
+ list.items[last] = `${list.items[last]}\n${line.trim()}`;
99
+ continue;
100
+ }
101
+ flushList();
102
+ paragraph.push(line);
103
+ }
104
+ flush();
105
+ return blocks;
106
+ }
107
+ /** Parses one run of inline Markdown. */
108
+ function parseInline(source) {
109
+ const nodes = [];
110
+ let text = "";
111
+ const pushText = (value) => {
112
+ text += value;
113
+ };
114
+ const pushNode = (node) => {
115
+ if (text !== "") nodes.push({
116
+ type: "text",
117
+ text
118
+ });
119
+ text = "";
120
+ nodes.push(node);
121
+ };
122
+ let index = 0;
123
+ while (index < source.length) {
124
+ const char = source[index];
125
+ if (char === "\\" && index + 1 < source.length && ESCAPABLE.test(source[index + 1])) {
126
+ pushText(source[index + 1]);
127
+ index += 2;
128
+ continue;
129
+ }
130
+ if (char === "`") {
131
+ const span = readCodeSpan(source, index);
132
+ if (span !== void 0) {
133
+ pushNode({
134
+ type: "code",
135
+ text: span.text
136
+ });
137
+ index = span.end;
138
+ continue;
139
+ }
140
+ const run = /^`+/.exec(source.slice(index))[0];
141
+ pushText(run);
142
+ index += run.length;
143
+ continue;
144
+ }
145
+ if (char === "[") {
146
+ const link = readLink(source, index);
147
+ if (link !== void 0) {
148
+ pushNode({
149
+ type: "link",
150
+ href: link.href,
151
+ children: parseInline(link.label)
152
+ });
153
+ index = link.end;
154
+ continue;
155
+ }
156
+ }
157
+ if ((char === "*" || char === "_") && source[index + 1] === char) {
158
+ const strong = readDelimited(source, index, char.repeat(2));
159
+ if (strong !== void 0) {
160
+ pushNode({
161
+ type: "strong",
162
+ children: parseInline(strong.inner)
163
+ });
164
+ index = strong.end;
165
+ continue;
166
+ }
167
+ pushText(char.repeat(2));
168
+ index += 2;
169
+ continue;
170
+ }
171
+ if (char === "*" || char === "_") {
172
+ const em = readDelimited(source, index, char);
173
+ if (em !== void 0) {
174
+ pushNode({
175
+ type: "em",
176
+ children: parseInline(em.inner)
177
+ });
178
+ index = em.end;
179
+ continue;
180
+ }
181
+ }
182
+ pushText(char);
183
+ index += 1;
184
+ }
185
+ if (text !== "") nodes.push({
186
+ type: "text",
187
+ text
188
+ });
189
+ return nodes;
190
+ }
191
+ /** A code span opened by the backtick run at `start`, closed by a run of the same length. */
192
+ function readCodeSpan(source, start) {
193
+ const run = /^`+/.exec(source.slice(start))[0];
194
+ let search = start + run.length;
195
+ while (search < source.length) {
196
+ const found = source.indexOf(run, search);
197
+ if (found === -1) return void 0;
198
+ const after = found + run.length;
199
+ if (source[after] === "`" || source[found - 1] === "`") {
200
+ search = after;
201
+ while (source[search] === "`") search += 1;
202
+ continue;
203
+ }
204
+ let text = source.slice(start + run.length, found).replace(/\n/g, " ");
205
+ if (text.length > 2 && text.startsWith(" ") && text.endsWith(" ") && text.trim() !== "") text = text.slice(1, -1);
206
+ return {
207
+ text,
208
+ end: after
209
+ };
210
+ }
211
+ }
212
+ /** `[label](href)` starting at the bracket; brackets in the label may nest. */
213
+ function readLink(source, start) {
214
+ let depth = 0;
215
+ let close = -1;
216
+ for (let index = start; index < source.length; index += 1) {
217
+ const char = source[index];
218
+ if (char === "\\") {
219
+ index += 1;
220
+ continue;
221
+ }
222
+ if (char === "[") depth += 1;
223
+ if (char === "]") {
224
+ depth -= 1;
225
+ if (depth === 0) {
226
+ close = index;
227
+ break;
228
+ }
229
+ }
230
+ }
231
+ if (close === -1 || source[close + 1] !== "(") return void 0;
232
+ const target = /^\(\s*<?([^\s()<>]*)>?(?:\s+"[^"]*")?\s*\)/.exec(source.slice(close + 1));
233
+ if (target === null) return void 0;
234
+ return {
235
+ label: source.slice(start + 1, close),
236
+ href: target[1],
237
+ end: close + 1 + target[0].length
238
+ };
239
+ }
240
+ /**
241
+ * Emphasis opened by `delimiter` at `start`: the inner text may not begin or
242
+ * end with a space, and an underscore only counts at a word boundary, so
243
+ * `snake_case_name` stays text.
244
+ */
245
+ function readDelimited(source, start, delimiter) {
246
+ const underscore = delimiter[0] === "_";
247
+ if (underscore && start > 0 && WORD_CHAR.test(source[start - 1])) return void 0;
248
+ const open = start + delimiter.length;
249
+ if (open >= source.length || /\s/.test(source[open])) return void 0;
250
+ let search = open;
251
+ while (search < source.length) {
252
+ const found = source.indexOf(delimiter, search);
253
+ if (found === -1) return void 0;
254
+ const end = found + delimiter.length;
255
+ if (delimiter.length === 1 && source[end] === delimiter) {
256
+ search = end + 1;
257
+ continue;
258
+ }
259
+ const inner = source.slice(open, found);
260
+ const boundaryOk = !underscore || end >= source.length || !WORD_CHAR.test(source[end]);
261
+ if (inner !== "" && !/\s/.test(inner[inner.length - 1]) && boundaryOk) return {
262
+ inner,
263
+ end
264
+ };
265
+ search = found + 1;
266
+ }
267
+ }
268
+
269
+ //#endregion
270
+ export { parseInline, parseMarkdown };
271
+ //# sourceMappingURL=markdown.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.mjs","names":[],"sources":["../../src/lib/markdown.ts"],"sourcesContent":["/*\n * A small Markdown parser for native message text: the subset an assistant\n * reply uses, parsed to plain data so the renderer and the tests share one\n * shape. Kept free of React Native so a unit test can run it in Node.\n *\n * Blocks: ATX headings, paragraphs, bullet and numbered lists, fenced code\n * (an unclosed fence runs to the end, so a streaming reply shows its code\n * before the closing fence arrives) and thematic breaks.\n * Inline: code spans, bold, italic, links and backslash escapes.\n *\n * ponytail: no tables, images, blockquotes, nested lists or setext headings\n * yet; their source falls through as paragraph text, so nothing is lost.\n */\n\nexport type MarkdownInline =\n | { type: 'text'; text: string }\n | { type: 'code'; text: string }\n | { type: 'strong'; children: MarkdownInline[] }\n | { type: 'em'; children: MarkdownInline[] }\n | { type: 'link'; href: string; children: MarkdownInline[] };\n\nexport type MarkdownHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport type MarkdownBlock =\n | { type: 'heading'; level: MarkdownHeadingLevel; children: MarkdownInline[] }\n | { type: 'paragraph'; children: MarkdownInline[] }\n | { type: 'list'; ordered: boolean; start: number; items: MarkdownInline[][] }\n | { type: 'code'; language: string | undefined; text: string }\n | { type: 'rule' };\n\nconst FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})[ \\t]*([^\\s`]*)/;\nconst HEADING = /^ {0,3}(#{1,6})(?:[ \\t]+(.*?))?(?:[ \\t]+#+)?[ \\t]*$/;\nconst RULE = /^ {0,3}([-*_])(?:[ \\t]*\\1){2,}[ \\t]*$/;\nconst BULLET_ITEM = /^ {0,3}[-*+][ \\t]+(.*)$/;\nconst ORDERED_ITEM = /^ {0,3}(\\d{1,9})[.)][ \\t]+(.*)$/;\nconst INDENTED = /^[ \\t]+\\S/;\nconst ESCAPABLE = /[!-/:-@[-`{-~]/;\nconst WORD_CHAR = /[\\p{L}\\p{N}]/u;\n\nfunction isBlank(line: string): boolean {\n return line.trim() === '';\n}\n\n/** Parses a Markdown document into blocks. */\nexport function parseMarkdown(source: string): MarkdownBlock[] {\n const lines = source.replace(/\\r\\n?/g, '\\n').split('\\n');\n const blocks: MarkdownBlock[] = [];\n let paragraph: string[] = [];\n let list: { ordered: boolean; start: number; items: string[] } | undefined;\n\n const flushParagraph = () => {\n if (paragraph.length > 0) blocks.push({ type: 'paragraph', children: parseInline(paragraph.join('\\n')) });\n paragraph = [];\n };\n const flushList = () => {\n if (list !== undefined)\n blocks.push({ type: 'list', ordered: list.ordered, start: list.start, items: list.items.map(parseInline) });\n list = undefined;\n };\n const flush = () => {\n flushParagraph();\n flushList();\n };\n\n for (let index = 0; index < lines.length; index += 1) {\n const line = lines[index]!;\n\n const fence = FENCE_OPEN.exec(line);\n if (fence !== null) {\n flush();\n const marker = fence[1]!;\n const close = new RegExp(`^ {0,3}${marker[0] === '`' ? '`' : '~'}{${marker.length},}[ \\\\t]*$`);\n const body: string[] = [];\n index += 1;\n while (index < lines.length && !close.test(lines[index]!)) {\n body.push(lines[index]!);\n index += 1;\n }\n const language = fence[2] === undefined || fence[2] === '' ? undefined : fence[2];\n blocks.push({ type: 'code', language, text: body.join('\\n') });\n continue;\n }\n\n if (isBlank(line)) {\n flush();\n continue;\n }\n\n const heading = HEADING.exec(line);\n if (heading !== null) {\n flush();\n const level = heading[1]!.length as MarkdownHeadingLevel;\n blocks.push({ type: 'heading', level, children: parseInline(heading[2] ?? '') });\n continue;\n }\n\n if (RULE.test(line)) {\n flush();\n blocks.push({ type: 'rule' });\n continue;\n }\n\n const bullet = BULLET_ITEM.exec(line);\n const ordered = bullet === null ? ORDERED_ITEM.exec(line) : null;\n if (bullet !== null || ordered !== null) {\n flushParagraph();\n const isOrdered = ordered !== null;\n if (list === undefined || list.ordered !== isOrdered) {\n flushList();\n list = { ordered: isOrdered, start: isOrdered ? Number(ordered[1]) : 1, items: [] };\n }\n list.items.push(isOrdered ? ordered[2]! : bullet![1]!);\n continue;\n }\n\n if (list !== undefined && INDENTED.test(line)) {\n const last = list.items.length - 1;\n list.items[last] = `${list.items[last]!}\\n${line.trim()}`;\n continue;\n }\n\n flushList();\n paragraph.push(line);\n }\n flush();\n return blocks;\n}\n\n/** Parses one run of inline Markdown. */\nexport function parseInline(source: string): MarkdownInline[] {\n const nodes: MarkdownInline[] = [];\n let text = '';\n const pushText = (value: string) => {\n text += value;\n };\n const pushNode = (node: MarkdownInline) => {\n if (text !== '') nodes.push({ type: 'text', text });\n text = '';\n nodes.push(node);\n };\n\n let index = 0;\n while (index < source.length) {\n const char = source[index]!;\n\n if (char === '\\\\' && index + 1 < source.length && ESCAPABLE.test(source[index + 1]!)) {\n pushText(source[index + 1]!);\n index += 2;\n continue;\n }\n\n if (char === '`') {\n const span = readCodeSpan(source, index);\n if (span !== undefined) {\n pushNode({ type: 'code', text: span.text });\n index = span.end;\n continue;\n }\n const run = /^`+/.exec(source.slice(index))![0];\n pushText(run);\n index += run.length;\n continue;\n }\n\n if (char === '[') {\n const link = readLink(source, index);\n if (link !== undefined) {\n pushNode({ type: 'link', href: link.href, children: parseInline(link.label) });\n index = link.end;\n continue;\n }\n }\n\n if ((char === '*' || char === '_') && source[index + 1] === char) {\n const strong = readDelimited(source, index, char.repeat(2));\n if (strong !== undefined) {\n pushNode({ type: 'strong', children: parseInline(strong.inner) });\n index = strong.end;\n continue;\n }\n pushText(char.repeat(2));\n index += 2;\n continue;\n }\n\n if (char === '*' || char === '_') {\n const em = readDelimited(source, index, char);\n if (em !== undefined) {\n pushNode({ type: 'em', children: parseInline(em.inner) });\n index = em.end;\n continue;\n }\n }\n\n pushText(char);\n index += 1;\n }\n if (text !== '') nodes.push({ type: 'text', text });\n return nodes;\n}\n\n/** A code span opened by the backtick run at `start`, closed by a run of the same length. */\nfunction readCodeSpan(source: string, start: number): { text: string; end: number } | undefined {\n const run = /^`+/.exec(source.slice(start))![0];\n let search = start + run.length;\n while (search < source.length) {\n const found = source.indexOf(run, search);\n if (found === -1) return undefined;\n const after = found + run.length;\n // A longer run is not the closer; skip past all of it.\n if (source[after] === '`' || source[found - 1] === '`') {\n search = after;\n while (source[search] === '`') search += 1;\n continue;\n }\n let text = source.slice(start + run.length, found).replace(/\\n/g, ' ');\n if (text.length > 2 && text.startsWith(' ') && text.endsWith(' ') && text.trim() !== '') text = text.slice(1, -1);\n return { text, end: after };\n }\n return undefined;\n}\n\n/** `[label](href)` starting at the bracket; brackets in the label may nest. */\nfunction readLink(source: string, start: number): { label: string; href: string; end: number } | undefined {\n let depth = 0;\n let close = -1;\n for (let index = start; index < source.length; index += 1) {\n const char = source[index];\n if (char === '\\\\') {\n index += 1;\n continue;\n }\n if (char === '[') depth += 1;\n if (char === ']') {\n depth -= 1;\n if (depth === 0) {\n close = index;\n break;\n }\n }\n }\n if (close === -1 || source[close + 1] !== '(') return undefined;\n const target = /^\\(\\s*<?([^\\s()<>]*)>?(?:\\s+\"[^\"]*\")?\\s*\\)/.exec(source.slice(close + 1));\n if (target === null) return undefined;\n return { label: source.slice(start + 1, close), href: target[1]!, end: close + 1 + target[0].length };\n}\n\n/**\n * Emphasis opened by `delimiter` at `start`: the inner text may not begin or\n * end with a space, and an underscore only counts at a word boundary, so\n * `snake_case_name` stays text.\n */\nfunction readDelimited(source: string, start: number, delimiter: string): { inner: string; end: number } | undefined {\n const underscore = delimiter[0] === '_';\n if (underscore && start > 0 && WORD_CHAR.test(source[start - 1]!)) return undefined;\n const open = start + delimiter.length;\n if (open >= source.length || /\\s/.test(source[open]!)) return undefined;\n let search = open;\n while (search < source.length) {\n const found = source.indexOf(delimiter, search);\n if (found === -1) return undefined;\n const end = found + delimiter.length;\n const single = delimiter.length === 1;\n // A single delimiter skips over a double one (`*a **b** c*`), which belongs to nested bold.\n if (single && source[end] === delimiter) {\n search = end + 1;\n continue;\n }\n const inner = source.slice(open, found);\n const boundaryOk = !underscore || end >= source.length || !WORD_CHAR.test(source[end]!);\n if (inner !== '' && !/\\s/.test(inner[inner.length - 1]!) && boundaryOk) return { inner, end };\n search = found + 1;\n }\n return undefined;\n}\n"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ //#region src/lib/tone.ts
2
+ /**
3
+ * The token each tone vocabulary reads as natively, the same pairs the web
4
+ * components name as classes. Components index the Unistyles theme with these,
5
+ * so a tone and its colour are named once.
6
+ */
7
+ /** The ink of a chip tone; neutral is quiet `dim`, every accent is itself. */
8
+ const CHIP_INK = {
9
+ neutral: "dim",
10
+ blue: "blue",
11
+ green: "green",
12
+ yellow: "yellow",
13
+ red: "red",
14
+ magenta: "magenta",
15
+ violet: "violet",
16
+ cyan: "cyan",
17
+ orange: "orange",
18
+ teal: "teal"
19
+ };
20
+ /** The ink and tinted fill of a status pill. Running stays yellow, matching the web. */
21
+ const STATUS_COLORS = {
22
+ neutral: {
23
+ ink: "faint",
24
+ fill: "panel"
25
+ },
26
+ running: {
27
+ ink: "yellow",
28
+ fill: "tint-yellow"
29
+ },
30
+ ok: {
31
+ ink: "green",
32
+ fill: "tint-green"
33
+ },
34
+ error: {
35
+ ink: "red",
36
+ fill: "tint-red"
37
+ },
38
+ info: {
39
+ ink: "blue",
40
+ fill: "tint-blue"
41
+ },
42
+ accent: {
43
+ ink: "magenta",
44
+ fill: "tint-magenta"
45
+ }
46
+ };
47
+
48
+ //#endregion
49
+ export { CHIP_INK, STATUS_COLORS };
50
+ //# sourceMappingURL=tone.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tone.mjs","names":[],"sources":["../../src/lib/tone.ts"],"sourcesContent":["import type { ChipTone, NativeColorToken, StatusTone } from '@agimon-ai/po-web-components/nativeTheme';\n\n/**\n * The token each tone vocabulary reads as natively, the same pairs the web\n * components name as classes. Components index the Unistyles theme with these,\n * so a tone and its colour are named once.\n */\n\n/** The ink of a chip tone; neutral is quiet `dim`, every accent is itself. */\nexport const CHIP_INK: Readonly<Record<ChipTone, NativeColorToken>> = {\n neutral: 'dim',\n blue: 'blue',\n green: 'green',\n yellow: 'yellow',\n red: 'red',\n magenta: 'magenta',\n violet: 'violet',\n cyan: 'cyan',\n orange: 'orange',\n teal: 'teal',\n};\n\n/** The ink and tinted fill of a status pill. Running stays yellow, matching the web. */\nexport const STATUS_COLORS: Readonly<Record<StatusTone, { ink: NativeColorToken; fill: NativeColorToken }>> = {\n neutral: { ink: 'faint', fill: 'panel' },\n running: { ink: 'yellow', fill: 'tint-yellow' },\n ok: { ink: 'green', fill: 'tint-green' },\n error: { ink: 'red', fill: 'tint-red' },\n info: { ink: 'blue', fill: 'tint-blue' },\n accent: { ink: 'magenta', fill: 'tint-magenta' },\n};\n"],"mappings":";;;;;;;AASA,MAAa,WAAyD;CACpE,SAAS;CACT,MAAM;CACN,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,MAAM;AACR;;AAGA,MAAa,gBAAiG;CAC5G,SAAS;EAAE,KAAK;EAAS,MAAM;CAAQ;CACvC,SAAS;EAAE,KAAK;EAAU,MAAM;CAAc;CAC9C,IAAI;EAAE,KAAK;EAAS,MAAM;CAAa;CACvC,OAAO;EAAE,KAAK;EAAO,MAAM;CAAW;CACtC,MAAM;EAAE,KAAK;EAAQ,MAAM;CAAY;CACvC,QAAQ;EAAE,KAAK;EAAW,MAAM;CAAe;AACjD"}
@@ -0,0 +1,22 @@
1
+ import { useState } from "react";
2
+
3
+ //#region src/lib/useControllable.ts
4
+ /**
5
+ * Controlled-or-uncontrolled state, the Radix convention every compound
6
+ * component follows: given `value` the caller owns it, otherwise the
7
+ * component keeps its own copy seeded from `defaultValue`. `onChange` fires
8
+ * either way.
9
+ */
10
+ function useControllable(value, defaultValue, onChange) {
11
+ const [own, setOwn] = useState(defaultValue);
12
+ const current = value === void 0 ? own : value;
13
+ const set = (next) => {
14
+ if (value === void 0) setOwn(next);
15
+ onChange?.(next);
16
+ };
17
+ return [current, set];
18
+ }
19
+
20
+ //#endregion
21
+ export { useControllable };
22
+ //# sourceMappingURL=useControllable.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useControllable.mjs","names":[],"sources":["../../src/lib/useControllable.ts"],"sourcesContent":["import { useState } from 'react';\n\n/**\n * Controlled-or-uncontrolled state, the Radix convention every compound\n * component follows: given `value` the caller owns it, otherwise the\n * component keeps its own copy seeded from `defaultValue`. `onChange` fires\n * either way.\n */\nexport function useControllable<T>(\n value: T | undefined,\n defaultValue: T,\n onChange: ((next: T) => void) | undefined,\n): [T, (next: T) => void] {\n const [own, setOwn] = useState(defaultValue);\n const current = value === undefined ? own : value;\n const set = (next: T) => {\n if (value === undefined) setOwn(next);\n onChange?.(next);\n };\n return [current, set];\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,gBACd,OACA,cACA,UACwB;CACxB,MAAM,CAAC,KAAK,UAAU,SAAS,YAAY;CAC3C,MAAM,UAAU,UAAU,SAAY,MAAM;CAC5C,MAAM,OAAO,SAAY;EACvB,IAAI,UAAU,QAAW,OAAO,IAAI;EACpC,WAAW,IAAI;CACjB;CACA,OAAO,CAAC,SAAS,GAAG;AACtB"}
@@ -0,0 +1,20 @@
1
+ import { Text } from "react-native-unistyles/components/native/Text";
2
+ import { Children } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ //#region src/lib/wrapText.tsx
6
+ /**
7
+ * React Native renders a string only inside <Text>, and a View passes no text
8
+ * style down. A component that accepts loose children wraps each bare string
9
+ * or number in a Text carrying its own type style, and leaves elements alone.
10
+ */
11
+ function wrapText(children, style) {
12
+ return Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx(Text, {
13
+ style,
14
+ children: child
15
+ }) : child);
16
+ }
17
+
18
+ //#endregion
19
+ export { wrapText };
20
+ //# sourceMappingURL=wrapText.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapText.mjs","names":["Children","ReactNode","StyleProp","TextStyle","wrapText","children","style","map","child"],"sources":["../../src/lib/wrapText.tsx"],"sourcesContent":["import { Children, type ReactNode } from 'react';\nimport { type StyleProp, Text, type TextStyle } from 'react-native';\n\n/**\n * React Native renders a string only inside <Text>, and a View passes no text\n * style down. A component that accepts loose children wraps each bare string\n * or number in a Text carrying its own type style, and leaves elements alone.\n */\nexport function wrapText(children: ReactNode, style: StyleProp<TextStyle>): ReactNode {\n return Children.map(children, (child) =>\n typeof child === 'string' || typeof child === 'number' ? <Text style={style}>{child}</Text> : child,\n );\n}\n"],"mappings":";;;;;;;;;;AAQA,SAAgBI,SAASC,UAAqBC,OAAwC;CACpF,OAAON,SAASO,IAAIF,WAAWG,UAC7B,OAAOA,UAAU,YAAY,OAAOA,UAAU,WAAW,oBAAC,MAAD;EAAaF;YAAQE;CAAY,KAAIA,KAChG;AACF"}
package/llms.txt ADDED
@@ -0,0 +1,8 @@
1
+ # @agimon-ai/po-native-components
2
+
3
+ Package-owned guidance for the Po React Native component library.
4
+
5
+ ## Resources
6
+
7
+ - [Package README](./README.md): What the library ships, where `PoNativeProvider` goes, each
8
+ component's web counterpart, and why the API only ever grows.
package/package.json ADDED
@@ -0,0 +1,104 @@
1
+ {
2
+ "name": "@agimon-ai/po-native-components",
3
+ "version": "0.0.0-alpha.0",
4
+ "description": "Shared React Native components for Po and its native plugins: the web component library's look and API on native parts, tuned to the Doom palette.",
5
+ "keywords": [
6
+ "ai",
7
+ "coding-agent",
8
+ "components",
9
+ "design-system",
10
+ "developer-tools",
11
+ "expo",
12
+ "po",
13
+ "react",
14
+ "react-native",
15
+ "theme",
16
+ "unistyles"
17
+ ],
18
+ "homepage": "https://agimon.ai",
19
+ "bugs": {
20
+ "url": "https://github.com/AgiFlow/po/issues"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Vuong Ngo",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/AgiFlow/po.git",
27
+ "directory": "packages/core/po-native-components"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "llms.txt",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "type": "module",
36
+ "types": "./dist/index.d.mts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.mts",
40
+ "default": "./dist/index.mjs"
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "dependencies": {
48
+ "@agimon-ai/po-web-components": "0.0.0-alpha.0"
49
+ },
50
+ "devDependencies": {
51
+ "@agimon-ai/po-build": "0.0.0-alpha.0",
52
+ "@agimon-ai/vibe-lint-plugin-doom-web": "0.0.0-alpha.0",
53
+ "@babel/core": "7.29.7",
54
+ "@expo/vector-icons": "15.1.1",
55
+ "@gorhom/bottom-sheet": "5.2.14",
56
+ "@react-native-segmented-control/segmented-control": "2.5.7",
57
+ "@shopify/flash-list": "2.0.2",
58
+ "@types/node": "26.6.4",
59
+ "@types/react": "19.3.0",
60
+ "expo": "57.0.27",
61
+ "expo-clipboard": "~57.0.2",
62
+ "expo-font": "~57.0.4",
63
+ "expo-haptics": "~57.0.3",
64
+ "expo-modules-core": "57.0.21",
65
+ "expo-symbols": "~57.0.3",
66
+ "react": "19.2.3",
67
+ "react-dom": "19.2.3",
68
+ "react-native": "0.86.3",
69
+ "react-native-gesture-handler": "~3.3.0",
70
+ "react-native-reanimated": "4.5.1",
71
+ "react-native-safe-area-context": "~5.7.0",
72
+ "react-native-unistyles": "3.5.2",
73
+ "react-native-worklets": "0.10.1",
74
+ "tsdown": "0.23.0",
75
+ "typescript": "7.0.2",
76
+ "vitest": "5.0.3"
77
+ },
78
+ "peerDependencies": {
79
+ "@expo/vector-icons": "^15.0.0",
80
+ "@gorhom/bottom-sheet": "^5.2.0",
81
+ "@react-native-segmented-control/segmented-control": "^2.5.0",
82
+ "@shopify/flash-list": "^2.0.0",
83
+ "expo-clipboard": "^57.0.0",
84
+ "expo-font": "^57.0.0",
85
+ "expo-haptics": "^57.0.0",
86
+ "expo-symbols": "^57.0.0",
87
+ "react": "^19.0.0",
88
+ "react-native": "^0.86.0",
89
+ "react-native-gesture-handler": "^2.32.0",
90
+ "react-native-reanimated": "^4.5.0",
91
+ "react-native-safe-area-context": "^5.7.0",
92
+ "react-native-unistyles": "^3.5.0"
93
+ },
94
+ "engines": {
95
+ "node": ">=24"
96
+ },
97
+ "scripts": {
98
+ "build": "tsdown",
99
+ "test": "vitest --run",
100
+ "typecheck": "tsc --noEmit",
101
+ "lint": "oxlint . && oxfmt . --check",
102
+ "fixcode": "oxlint . --fix && oxfmt ."
103
+ }
104
+ }