@octane-xplat/ui 0.7.3 → 0.9.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 (195) hide show
  1. package/README.md +4 -3
  2. package/dist/native/Button.tsrx.js +1 -1
  3. package/dist/native/KeyboardAvoiding.mobile.tsrx.js +2 -2
  4. package/dist/native/Markdown.tsrx.js +233 -0
  5. package/dist/native/Overlay.tsrx.js +15 -26
  6. package/dist/native/PinInput.tsrx.js +25 -7
  7. package/dist/native/Popover.tsrx.js +17 -18
  8. package/dist/native/Pressable.tsrx.js +4 -1
  9. package/dist/native/SearchInput.tsrx.js +6 -3
  10. package/dist/native/Sheet.tsrx.js +22 -37
  11. package/dist/native/TextArea.tsrx.js +6 -3
  12. package/dist/native/TextInput.tsrx.js +6 -3
  13. package/dist/native/VirtualList.tsrx.js +305 -121
  14. package/dist/native/index.shared.js +7 -5
  15. package/dist/native/keyboard-inset.mobile.js +5 -5
  16. package/dist/native/navigation-request.js +26 -0
  17. package/dist/native/octane-client-build.json +1 -1
  18. package/dist/native/overlay-lifetime.mobile.js +65 -0
  19. package/dist/native/pan.tsrx.js +16 -2
  20. package/dist/native/route-table.js +90 -10
  21. package/dist/native/route.js +26 -16
  22. package/dist/native/shared.js +7 -5
  23. package/dist/native/sheet-service.js +1 -1
  24. package/dist/native/svg.mobile.js +1 -1
  25. package/dist/native/text-focus.js +10 -0
  26. package/dist/native/text-write.js +18 -11
  27. package/dist/native/toast-anchor.tsrx.js +1 -1
  28. package/dist/native/ui.js +7 -6
  29. package/dist/native/vendor/ui-svg/index.android.js +2 -2
  30. package/dist/native/vendor/ui-svg/index.ios.js +2 -2
  31. package/dist/native/vendor/ui-svg/{index.common.js → src/index.common.js} +1 -1
  32. package/dist/native/virtual-list-cell-pool.js +63 -0
  33. package/dist/web/Button.web.tsrx.js +1 -1
  34. package/dist/web/KeyboardAvoiding.web.tsrx.js +78 -0
  35. package/dist/web/Markdown.tsrx.js +98 -0
  36. package/dist/web/Overlay.web.tsrx.js +81 -32
  37. package/dist/web/PinInput.web.tsrx.js +24 -10
  38. package/dist/web/Pressable.web.tsrx.js +169 -53
  39. package/dist/web/SearchInput.web.tsrx.js +2 -2
  40. package/dist/web/Sheet.web.tsrx.js +20 -7
  41. package/dist/web/TextArea.web.tsrx.js +22 -17
  42. package/dist/web/TextInput.web.tsrx.js +2 -2
  43. package/dist/web/VirtualList.web.tsrx.js +220 -109
  44. package/dist/web/WebView.web.tsrx.js +3 -3
  45. package/dist/web/{index.shared.js → index.shared.web.js} +7 -5
  46. package/dist/web/modal-focus.web.js +95 -0
  47. package/dist/web/navigation-request.js +26 -0
  48. package/dist/web/octane-client-build.json +1 -1
  49. package/dist/web/pan.web.tsrx.js +27 -10
  50. package/dist/web/route-table.js +90 -10
  51. package/dist/web/route.web.js +88 -22
  52. package/dist/web/sheet-service.web.js +8 -0
  53. package/dist/web/theme/colorScheme.web.js +31 -4
  54. package/dist/web/ui.js +8 -6
  55. package/dist/web/virtual-list-cell-pool.js +63 -0
  56. package/package.json +21 -19
  57. package/platforms/android/native-api-usage.json +7 -7
  58. package/src/CommandPalette.tsrx +1 -0
  59. package/src/Grid.tsrx +2 -0
  60. package/src/Icon.macos.tsrx +1 -0
  61. package/src/KeyboardAvoiding.macos.tsrx +7 -1
  62. package/src/KeyboardAvoiding.mobile.tsrx +2 -2
  63. package/src/KeyboardAvoiding.tsrx +15 -0
  64. package/src/KeyboardAvoiding.web.tsrx +15 -0
  65. package/src/Markdown.tsrx +121 -0
  66. package/src/Meter.tsrx +1 -0
  67. package/src/Overlay.tsrx +15 -30
  68. package/src/Overlay.web.tsrx +12 -3
  69. package/src/PinInput.macos.tsrx +20 -6
  70. package/src/PinInput.mobile.test.ts +107 -0
  71. package/src/PinInput.tsrx +20 -6
  72. package/src/PinInput.web.test.tsrx +42 -0
  73. package/src/PinInput.web.tsrx +20 -6
  74. package/src/Popover.tsrx +17 -17
  75. package/src/Pressable.tsrx +1 -1
  76. package/src/Pressable.web.test.tsrx +36 -0
  77. package/src/Pressable.web.tsrx +37 -6
  78. package/src/RouteHost.macos.tsrx +1 -0
  79. package/src/SearchInput.tsrx +4 -3
  80. package/src/SearchInput.web.tsrx +1 -1
  81. package/src/Sheet.tsrx +20 -41
  82. package/src/Sheet.web.tsrx +9 -1
  83. package/src/Text.tsrx +2 -0
  84. package/src/TextArea.tsrx +6 -5
  85. package/src/TextArea.web.test.tsrx +39 -0
  86. package/src/TextArea.web.tsrx +7 -5
  87. package/src/TextInput.tsrx +6 -6
  88. package/src/TextInput.web.tsrx +1 -1
  89. package/src/VirtualList.macos.tsrx +93 -6
  90. package/src/VirtualList.mobile.test.tsrx +232 -0
  91. package/src/VirtualList.tsrx +285 -81
  92. package/src/VirtualList.web.tsrx +131 -25
  93. package/src/WebView.tsrx +1 -0
  94. package/src/WebView.web.tsrx +3 -0
  95. package/src/android/BottomNavigationView.android.tsrx +1 -0
  96. package/src/android/MaterialDialog.android.tsrx +1 -0
  97. package/src/anim.macos.tsrx +1 -0
  98. package/src/apply-native-modifiers.native.ts +4 -1
  99. package/src/child-array.ts +12 -7
  100. package/src/colorScheme.macos.ts +1 -0
  101. package/src/controls.macos.tsrx +4 -1
  102. package/src/data-driver.mobile.test.ts +120 -0
  103. package/src/data-lifecycle.mobile.test.ts +251 -0
  104. package/src/escape-props.ts +2 -0
  105. package/src/grid-auto-placement.ts +54 -12
  106. package/src/grid-placement.ts +1 -1
  107. package/src/hosted-unsupported.macos.tsrx +1 -0
  108. package/src/index.macos.ts +23 -3
  109. package/src/index.mobile.ts +0 -1
  110. package/src/index.shared.ts +22 -1
  111. package/src/index.shared.web.ts +291 -0
  112. package/src/index.web.ts +1 -1
  113. package/src/input-readiness.web.test.tsrx +82 -0
  114. package/src/ios/UITabBar.ios.tsrx +1 -0
  115. package/src/keyboard-inset.mobile.test.ts +62 -0
  116. package/src/keyboard-inset.mobile.ts +63 -43
  117. package/src/layout-shells.macos.tsrx +1 -5
  118. package/src/macos-extras.macos.tsrx +2 -0
  119. package/src/modal-focus.web.test.tsrx +63 -0
  120. package/src/modal-focus.web.ts +162 -0
  121. package/src/navigation-request.ts +37 -0
  122. package/src/overlay-lifecycle.mobile.test.ts +316 -0
  123. package/src/overlay-lifetime.mobile.ts +107 -0
  124. package/src/pan.mobile.test.tsrx +116 -0
  125. package/src/pan.tsrx +20 -2
  126. package/src/pan.web.tsrx +35 -7
  127. package/src/platformProps.ts +1 -0
  128. package/src/popover.mobile.test.ts +9 -1
  129. package/src/pressable-accessibility.mobile.test.ts +30 -0
  130. package/src/props.ts +163 -3
  131. package/src/refresh.ts +6 -1
  132. package/src/refresh.web.test.ts +77 -77
  133. package/src/route-android.test.ts +162 -0
  134. package/src/route-history.web.test.ts +80 -0
  135. package/src/route-navigation.web.test.ts +173 -0
  136. package/src/route-table.test.ts +188 -9
  137. package/src/route-table.ts +138 -10
  138. package/src/route.macos.ts +56 -13
  139. package/src/route.ts +54 -24
  140. package/src/route.web.ts +141 -24
  141. package/src/sheet-detents.ts +5 -3
  142. package/src/sheet-service.macos.ts +5 -1
  143. package/src/sheet-service.web.ts +8 -0
  144. package/src/sheet-snap.test.ts +23 -23
  145. package/src/sheet-snap.ts +6 -1
  146. package/src/svg.mobile.ts +9 -3
  147. package/src/tap-to-blur.ios.ts +48 -32
  148. package/src/tap-to-blur.mobile.ts +23 -15
  149. package/src/text-focus.ts +12 -0
  150. package/src/text-input.mobile.test.ts +89 -0
  151. package/src/text-write.ts +21 -11
  152. package/src/theme/colorScheme.linux.ts +2 -4
  153. package/src/theme/colorScheme.web.ts +51 -4
  154. package/src/theme/theme-scheme.macos.ts +8 -2
  155. package/src/theme/tokens.css +1736 -1730
  156. package/src/translate.macos.ts +4 -1
  157. package/src/virtual-list-cell-pool.test.ts +53 -0
  158. package/src/virtual-list-cell-pool.ts +81 -0
  159. package/src/virtual-list-layout.test.ts +11 -8
  160. package/src/virtual-list-layout.ts +4 -8
  161. package/src/windows.linux.ts +7 -2
  162. package/src/windows.macos.ts +1 -0
  163. package/types/generated/.tsrx-typegen-manifest.json +13 -3
  164. package/types/generated/KeyboardAvoiding.d.ts +3 -0
  165. package/types/generated/KeyboardAvoiding.web.d.ts +2 -0
  166. package/types/generated/Markdown.d.ts +59 -0
  167. package/types/generated/TextArea.d.ts +2 -2
  168. package/types/generated/TextArea.web.d.ts +1 -1
  169. package/types/generated/TextInput.d.ts +2 -3
  170. package/types/generated/VirtualList.d.ts +3 -3
  171. package/types/generated/index.mobile.d.ts +0 -1
  172. package/types/generated/index.shared.d.ts +6 -3
  173. package/types/generated/index.shared.web.d.ts +114 -0
  174. package/types/generated/index.web.d.ts +1 -1
  175. package/types/generated/modal-focus.web.d.ts +3 -0
  176. package/types/generated/navigation-request.d.ts +10 -0
  177. package/types/generated/overlay-lifetime.mobile.d.ts +10 -0
  178. package/types/generated/props.d.ts +111 -3
  179. package/types/generated/route-table.d.ts +14 -3
  180. package/types/generated/svg.mobile.d.ts +2 -2
  181. package/types/generated/text-focus.d.ts +3 -0
  182. package/types/generated/text-write.d.ts +3 -1
  183. package/types/generated/theme/colorScheme.web.d.ts +5 -0
  184. package/types/generated/virtual-list-cell-pool.d.ts +18 -0
  185. package/types/index.macos.d.ts +15 -3
  186. /package/src/vendor/ui-svg/{index.android.ts → src/index.android.ts} +0 -0
  187. /package/src/vendor/ui-svg/{index.common.ts → src/index.common.ts} +0 -0
  188. /package/src/vendor/ui-svg/{index.ios.ts → src/index.ios.ts} +0 -0
  189. /package/src/vendor/ui-svg/{index.ts → src/index.ts} +0 -0
  190. /package/src/vendor/ui-svg/{typings → src/typings}/SVGKit.d.ts +0 -0
  191. /package/src/vendor/ui-svg/{typings → src/typings}/android.d.ts +0 -0
  192. /package/src/vendor/ui-svg/{typings → src/typings}/ios.d.ts +0 -0
  193. /package/types/generated/vendor/ui-svg/{index.common.d.ts → src/index.common.d.ts} +0 -0
  194. /package/types/generated/vendor/ui-svg/{index.d.ts → src/index.d.ts} +0 -0
  195. /package/types/generated/vendor/ui-svg/{index.ios.d.ts → src/index.ios.d.ts} +0 -0
@@ -1,5 +1,8 @@
1
1
  export function setTranslate(view: any, x = 0, y = 0): void {
2
- if (!view) {return}
2
+ if (!view) {
3
+ return
4
+ }
5
+
3
6
  view.translateX = x
4
7
  view.translateY = y
5
8
  }
@@ -0,0 +1,53 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { VirtualListCellPool } from './virtual-list-cell-pool'
3
+ import { createVirtualListEntries } from './virtual-list-layout'
4
+
5
+ const item = (id: string, type = 'row') => ({ id, type })
6
+ const entriesFor = (items: ReturnType<typeof item>[]) =>
7
+ createVirtualListEntries(
8
+ items,
9
+ (row) => row.id,
10
+ (row) => row.type,
11
+ )
12
+
13
+ describe('VirtualList physical cell ownership', () => {
14
+ it('retains keyed hosts across prepend and recycles only compatible free hosts', () => {
15
+ const items = [item('a'), item('b'), item('c', 'other')]
16
+ const pool = new VirtualListCellPool<ReturnType<typeof item>>()
17
+ const initial = pool.update(entriesFor(items))
18
+ const a = initial.find((cell) => cell.entry?.key === 'a')!
19
+ const b = initial.find((cell) => cell.entry?.key === 'b')!
20
+ const c = initial.find((cell) => cell.entry?.key === 'c')!
21
+ const next = pool.update(entriesFor([item('new'), items[1], items[2]]))
22
+ expect(next.find((cell) => cell.entry?.key === 'new')!.id).toBe(a.id)
23
+ expect(next.find((cell) => cell.entry?.key === 'b')!.id).toBe(b.id)
24
+ expect(next.find((cell) => cell.entry?.key === 'c')!.id).toBe(c.id)
25
+ expect(pool.isCurrent(a.id, a.entry!.rowKey, a.generation)).toBe(false)
26
+ const prepended = pool.update(entriesFor([item('first'), item('new'), items[1], items[2]]))
27
+ expect(prepended.find((cell) => cell.entry?.key === 'b')!.id).toBe(b.id)
28
+ })
29
+
30
+ it('does not recycle a host across types and bounds free hosts after repeated changes', () => {
31
+ const pool = new VirtualListCellPool<ReturnType<typeof item>>()
32
+ const original = pool.update(entriesFor([item('first', 'type0')]))[0]
33
+ const different = pool.update(entriesFor([item('next', 'type1')])).find((cell) => cell.entry)!
34
+ expect(different.id).not.toBe(original.id)
35
+ for (let index = 2; index < 1000; index++) {
36
+ const cells = pool.update(entriesFor([item(String(index), 'type' + index)]))
37
+ expect(cells.length).toBeLessThanOrEqual(9)
38
+ }
39
+ })
40
+
41
+ it('invalidates work on item replacement, emptying, restoration and disposal', () => {
42
+ const pool = new VirtualListCellPool<ReturnType<typeof item>>()
43
+ const first = pool.update(entriesFor([item('same')]))[0]
44
+ const replacement = pool.update(entriesFor([item('same')]))[0]
45
+ expect(replacement.id).toBe(first.id)
46
+ expect(pool.isCurrent(first.id, first.entry!.rowKey, first.generation)).toBe(false)
47
+ expect(pool.update([])).toEqual([])
48
+ const restored = pool.update(entriesFor([item('same')]))[0]
49
+ expect(restored.id).not.toBe(first.id)
50
+ pool.clear()
51
+ expect(pool.isCurrent(restored.id, restored.entry!.rowKey, restored.generation)).toBe(false)
52
+ })
53
+ })
@@ -0,0 +1,81 @@
1
+ import type { VirtualListEntry } from './virtual-list-layout'
2
+
3
+ export interface VirtualListCell<T> {
4
+ id: number
5
+ typeKey: string
6
+ generation: number
7
+ entry: VirtualListEntry<T> | null
8
+ rows: readonly VirtualListEntry<T>[]
9
+ }
10
+
11
+ /** Reuse physical hosts without retaining an off-window logical row subtree. */
12
+ export class VirtualListCellPool<T> {
13
+ private cells: VirtualListCell<T>[] = []
14
+ private byId = new Map<number, VirtualListCell<T>>()
15
+ private nextId = 0
16
+
17
+ update(entries: readonly VirtualListEntry<T>[]): readonly VirtualListCell<T>[] {
18
+ if (entries.length === 0) {
19
+ this.clear()
20
+ return this.cells
21
+ }
22
+
23
+ const wanted = new Set(entries.map((entry) => entry.rowKey))
24
+ let cells = this.cells.map((cell) =>
25
+ cell.entry && !wanted.has(cell.entry.rowKey)
26
+ ? { ...cell, entry: null, rows: [], generation: cell.generation + 1 }
27
+ : cell,
28
+ )
29
+
30
+ const retained = new Map(
31
+ cells.filter((cell) => cell.entry).map((cell) => [cell.entry!.rowKey, cell.id]),
32
+ )
33
+
34
+ for (const entry of entries) {
35
+ const retainedId = retained.get(entry.rowKey)
36
+ let index =
37
+ retainedId === undefined
38
+ ? cells.findIndex((cell) => !cell.entry && cell.typeKey === entry.typeKey)
39
+ : cells.findIndex((cell) => cell.id === retainedId)
40
+
41
+ if (index === -1) {
42
+ index = cells.length
43
+ cells.push({
44
+ id: this.nextId++,
45
+ typeKey: entry.typeKey,
46
+ generation: 0,
47
+ entry: null,
48
+ rows: [],
49
+ })
50
+ }
51
+
52
+ const cell = cells[index]
53
+ if (cell.entry !== entry) {
54
+ // Immutable snapshots let renderer caches see assignment/index changes.
55
+ cells[index] = { ...cell, entry, rows: [entry], generation: cell.generation + 1 }
56
+ }
57
+ }
58
+
59
+ let spare = 0
60
+ cells = cells.filter((cell) => cell.entry || spare++ < 8)
61
+ cells.sort((a, b) => (a.entry?.index ?? Infinity) - (b.entry?.index ?? Infinity) || a.id - b.id)
62
+ this.cells = cells
63
+ this.byId = new Map(cells.map((cell) => [cell.id, cell]))
64
+ return cells
65
+ }
66
+
67
+ get(id: number): VirtualListCell<T> | undefined {
68
+ return this.byId.get(id)
69
+ }
70
+
71
+ isCurrent(id: number, rowKey: string, generation: number): boolean {
72
+ const cell = this.byId.get(id)
73
+ return cell?.entry?.rowKey === rowKey && cell.generation === generation
74
+ }
75
+
76
+ clear() {
77
+ this.cells = []
78
+ this.byId.clear()
79
+ // IDs remain monotonic across empty/restore so old work cannot match.
80
+ }
81
+ }
@@ -48,10 +48,9 @@ describe('VirtualList size index', () => {
48
48
  })
49
49
 
50
50
  it('rejects duplicate item keys', () => {
51
- expect(() => createVirtualListEntries(
52
- [{ id: 'same' }, { id: 'same' }],
53
- (item) => item.id,
54
- )).toThrow('duplicate key')
51
+ expect(() =>
52
+ createVirtualListEntries([{ id: 'same' }, { id: 'same' }], (item) => item.id),
53
+ ).toThrow('duplicate key')
55
54
  })
56
55
 
57
56
  it('uses a type estimate only after four rows are measured', () => {
@@ -61,10 +60,14 @@ describe('VirtualList size index', () => {
61
60
  () => 'row',
62
61
  )
63
62
 
64
- const measurements = new Map(entries.slice(0, 3).map((entry, index) => [
65
- virtualListMeasurementKey(entry.rowKey, false),
66
- { width: 100, height: 36 + index * 12 },
67
- ]))
63
+ const measurements = new Map(
64
+ entries
65
+ .slice(0, 3)
66
+ .map((entry, index) => [
67
+ virtualListMeasurementKey(entry.rowKey, false),
68
+ { width: 100, height: 36 + index * 12 },
69
+ ]),
70
+ )
68
71
 
69
72
  expect(estimateVirtualListSizes(entries, false, 100, measurements)[3]).toBe(
70
73
  VIRTUAL_LIST_ESTIMATED_ROW_SIZE,
@@ -38,7 +38,9 @@ export function createVirtualListEntries<T>(
38
38
 
39
39
  const keyToken = JSON.stringify([typeof key, key])
40
40
  if (seen.has(keyToken)) {
41
- throw new Error(`VirtualList keyExtractor returned a duplicate key at index ${index}: ${String(key)}`)
41
+ throw new Error(
42
+ `VirtualList keyExtractor returned a duplicate key at index ${index}: ${String(key)}`,
43
+ )
42
44
  }
43
45
 
44
46
  seen.add(keyToken)
@@ -89,12 +91,7 @@ export function estimateVirtualListSizes<T>(
89
91
  )
90
92
 
91
93
  const cached = measurements.get(cacheKey)
92
- if (
93
- cached &&
94
- width > 0 &&
95
- cached.width > 0 &&
96
- Math.abs(cached.width - width) < 0.5
97
- ) {
94
+ if (cached && width > 0 && cached.width > 0 && Math.abs(cached.width - width) < 0.5) {
98
95
  return cached.height
99
96
  }
100
97
 
@@ -130,7 +127,6 @@ export class VirtualListSizeIndex {
130
127
  this.tree[parent] += this.tree[index]
131
128
  }
132
129
  }
133
-
134
130
  }
135
131
 
136
132
  get(index: number): number {
@@ -32,6 +32,7 @@ export function openWindow(
32
32
  const closed = new Promise<void>((resolve) => {
33
33
  resolveClosed = resolve
34
34
  })
35
+
35
36
  const off = bridge().on('windows', 'closed', (wid: unknown) => {
36
37
  if (wid === id) {
37
38
  off()
@@ -50,10 +51,14 @@ export function openWindow(
50
51
  id,
51
52
  closed,
52
53
  close() {
53
- void bridge().call('windows', 'close', [id]).catch(() => {})
54
+ void bridge()
55
+ .call('windows', 'close', [id])
56
+ .catch(() => {})
54
57
  },
55
58
  setTitle(title: string) {
56
- void bridge().call('windows', 'setTitle', [id, title]).catch(() => {})
59
+ void bridge()
60
+ .call('windows', 'setTitle', [id, title])
61
+ .catch(() => {})
57
62
  },
58
63
  }
59
64
  }
@@ -6,5 +6,6 @@ export function openWindow(options: OpenWindowOptions = {}): void {
6
6
  console.warn('[octane-xplat] Window creation is unsupported by the current AppKit host.')
7
7
  return
8
8
  }
9
+
9
10
  open(options)
10
11
  }
@@ -64,11 +64,14 @@
64
64
  "InputTags.web.d.ts",
65
65
  "Kbd.d.ts",
66
66
  "Kbd.web.d.ts",
67
+ "KeyboardAvoiding.d.ts",
67
68
  "KeyboardAvoiding.mobile.d.ts",
69
+ "KeyboardAvoiding.web.d.ts",
68
70
  "Link.d.ts",
69
71
  "Link.web.d.ts",
70
72
  "ListItem.d.ts",
71
73
  "ListItem.web.d.ts",
74
+ "Markdown.d.ts",
72
75
  "Meter.d.ts",
73
76
  "Meter.web.d.ts",
74
77
  "NavLink.d.ts",
@@ -176,6 +179,7 @@
176
179
  "index.linux.d.ts",
177
180
  "index.mobile.d.ts",
178
181
  "index.shared.d.ts",
182
+ "index.shared.web.d.ts",
179
183
  "index.web.d.ts",
180
184
  "ios/LiquidGlass.ios.d.ts",
181
185
  "ios/LiquidGlassContainer.ios.d.ts",
@@ -193,9 +197,12 @@
193
197
  "layout-child.d.ts",
194
198
  "layout-child.web.d.ts",
195
199
  "meter-math.d.ts",
200
+ "modal-focus.web.d.ts",
196
201
  "modal-presenter.mobile.d.ts",
197
202
  "modifier-factories.d.ts",
198
203
  "native/index.d.ts",
204
+ "navigation-request.d.ts",
205
+ "overlay-lifetime.mobile.d.ts",
199
206
  "pan.d.ts",
200
207
  "pan.web.d.ts",
201
208
  "platform.d.ts",
@@ -227,10 +234,12 @@
227
234
  "svg.mobile.d.ts",
228
235
  "tap-to-blur.ios.d.ts",
229
236
  "tap-to-blur.mobile.d.ts",
237
+ "text-focus.d.ts",
230
238
  "text-write.d.ts",
231
239
  "text-write.web.d.ts",
232
240
  "theme/colorScheme.d.ts",
233
241
  "theme/colorScheme.linux.d.ts",
242
+ "theme/colorScheme.web.d.ts",
234
243
  "theme/status-bar-scheme.mobile.d.ts",
235
244
  "theme/theme-scheme.d.ts",
236
245
  "toast-anchor.d.ts",
@@ -246,9 +255,10 @@
246
255
  "use-store.web.d.ts",
247
256
  "useMeasure.d.ts",
248
257
  "useMeasure.web.d.ts",
249
- "vendor/ui-svg/index.common.d.ts",
250
- "vendor/ui-svg/index.d.ts",
251
- "vendor/ui-svg/index.ios.d.ts",
258
+ "vendor/ui-svg/src/index.common.d.ts",
259
+ "vendor/ui-svg/src/index.d.ts",
260
+ "vendor/ui-svg/src/index.ios.d.ts",
261
+ "virtual-list-cell-pool.d.ts",
252
262
  "virtual-list-layout.d.ts",
253
263
  "web/index.d.ts",
254
264
  "windows.d.ts",
@@ -0,0 +1,3 @@
1
+ /** @jsxImportSource @nativescript-community/octane */
2
+ import type { KeyboardAvoidingProps } from './props.js';
3
+ export declare function KeyboardAvoiding(props: KeyboardAvoidingProps): unknown;
@@ -0,0 +1,2 @@
1
+ import type { KeyboardAvoidingProps } from './props.js';
2
+ export declare function KeyboardAvoiding(props: KeyboardAvoidingProps): import("octane/jsx-runtime").JSX.Element;
@@ -0,0 +1,59 @@
1
+ /** Markdown AST — the serialized shape `xplat routes` bakes for `.md`
2
+ * routes (parse happens at codegen, not runtime). `MdNode` covers block
3
+ * level; `MdInline` covers text runs inside paragraphs/lists/quotes. */
4
+ export type MdInline = {
5
+ t: 'text';
6
+ text: string;
7
+ } | {
8
+ t: 'code';
9
+ text: string;
10
+ } | {
11
+ t: 'bold';
12
+ children: MdInline[];
13
+ } | {
14
+ t: 'em';
15
+ children: MdInline[];
16
+ } | {
17
+ t: 'link';
18
+ text: string;
19
+ href: string;
20
+ };
21
+ export type MdNode = {
22
+ t: 'h';
23
+ depth: 1 | 2 | 3 | 4 | 5 | 6;
24
+ children: MdInline[];
25
+ } | {
26
+ t: 'p';
27
+ children: MdInline[];
28
+ } | {
29
+ t: 'code';
30
+ lang?: string;
31
+ text: string;
32
+ } | {
33
+ t: 'list';
34
+ ordered: boolean;
35
+ items: MdInline[][];
36
+ } | {
37
+ t: 'quote';
38
+ children: MdInline[];
39
+ } | {
40
+ t: 'hr';
41
+ };
42
+ export interface MdDoc {
43
+ kind: 'octane-xplat/md';
44
+ v: 1;
45
+ children: MdNode[];
46
+ }
47
+ /** Renders a baked markdown doc with the shared vocabulary — Text
48
+ * blocks on every platform, no parser at runtime. `data` is the AST the
49
+ * codegen baked into routes.gen.data (or a doc built programmatically). */
50
+ export declare function Markdown(props: {
51
+ data?: MdDoc;
52
+ }): unknown;
53
+ /** Route screen for `.md` files — the codegen emits specs with this as
54
+ * `screen`, so a markdown file in the route dir is a route end-to-end.
55
+ * Receives baked data like any route (`props.data`). */
56
+ export declare function MarkdownScreen(props: {
57
+ data?: MdDoc;
58
+ error?: unknown;
59
+ }): unknown;
@@ -3,6 +3,6 @@ import type { TextAreaProps } from "./props.js";
3
3
  * `autoGrow` is its default; `rows`/`maxRows` have no NS equivalent, so the
4
4
  * leaf converts them to min/maxHeight in dips using the widget's own line
5
5
  * height (iOS `font.lineHeight`, Android `getLineHeight()` px→dip — measured
6
- * on `loaded`, re-fit every commit for prop/style changes). The driver's
7
- * text→textChange echo suppression applies here unchanged. */
6
+ * on `loaded`, re-fit every commit for prop/style changes). Imperative
7
+ * writes suppress their synchronous textChange echo through text-write. */
8
8
  export declare function TextArea(props: TextAreaProps): unknown;
@@ -1,6 +1,6 @@
1
1
  import type { TextAreaProps } from "./props.js";
2
2
  /** Multiline input — <textarea>. `autoGrow` re-fits height to content after
3
- * every commit via scrollHeight, capped by `maxRows` translated to a real
3
+ * input and value updates via scrollHeight, capped by `maxRows` translated to a real
4
4
  * max-height from the element's computed line-height; past the cap the
5
5
  * field scrolls. `useLayoutEffect` so the measure lands pre-paint in the
6
6
  * commit that wrote `value`. Deps are explicit — tsrx infers them from the
@@ -1,7 +1,6 @@
1
1
  import type { TextInputProps } from "./props.js";
2
- /** Controlled single-line input. The driver suppresses the textChange echo
3
- * of its own `text` writes (upstream #5, since 0.2.1) — no leaf-side
4
- * guard needed. `editable` defaults true at the leaf too: an undefined
2
+ /** Controlled single-line input. Imperative writes suppress their synchronous
3
+ * textChange echo through text-write. `editable` defaults true: an undefined
5
4
  * write coerces ios.userInteractionEnabled to NO (dead field) — the
6
5
  * driver's skip-undefined patch covers it, the ?? stays as documentation.
7
6
  * `text` isn't a bound prop: the leaf writes it imperatively so the
@@ -1,5 +1,5 @@
1
1
  import type { VirtualListProps } from './props.js';
2
- /** Shared vertical virtualization over NativeScript ScrollView. Off-window
3
- * rows unmount; measured row-height changes above the visible anchor adjust
4
- * the native scroll offset after layout. */
2
+ /** Shared vertical virtualization with pooled outer hosts and keyed logical
3
+ * rows. Off-window item subtrees unmount; measured heights position cells and
4
+ * preserve the visible keyed anchor after layout. */
5
5
  export declare function VirtualList<T = any>(props: VirtualListProps<T>): unknown;
@@ -1,4 +1,3 @@
1
1
  export * from './index.shared.js';
2
2
  export { KeyboardAvoiding } from './KeyboardAvoiding.mobile.js';
3
- export type { KeyboardAvoidingProps } from './props.js';
4
3
  import './theme/status-bar-scheme.mobile.js';
@@ -8,6 +8,8 @@ export type { PanEvent, SwipeEvent, SetTranslate } from './props.js';
8
8
  export { setTranslate } from './translate.js';
9
9
  export { Spacer } from './Spacer.js';
10
10
  export { Text } from './Text.js';
11
+ export { Markdown, MarkdownScreen } from './Markdown.js';
12
+ export type { MdDoc, MdNode, MdInline } from './Markdown.js';
11
13
  export { RichText, RichTextSpan } from './RichText.js';
12
14
  export { Pressable } from './Pressable.js';
13
15
  export { Button } from './Button.js';
@@ -83,6 +85,7 @@ export { Tabs } from './Tabs.js';
83
85
  export type { TabSpec } from './Tabs.js';
84
86
  export { Switch } from './Switch.js';
85
87
  export { SafeArea } from './SafeArea.js';
88
+ export { KeyboardAvoiding } from './KeyboardAvoiding.js';
86
89
  export { Drawer } from './Drawer.js';
87
90
  export { useSafeAreaInsets } from './safeAreaInsets.js';
88
91
  export type { SafeAreaInsets } from './safeAreaInsets.js';
@@ -100,12 +103,12 @@ export { isNative } from './platform.js';
100
103
  export { registerStack, getStack, stackEntries } from './stacks.js';
101
104
  export { pushRoute, popRoute, routeStacks, pushDeepLink, routeFor, currentRoute, currentModalRoute, canGoBack, useCanGoBack, useRoute, useModalRoute, redirect, addBackInterceptor, registerScreens, registerRoutes, addRoutes, screenFor, hrefFor, layoutsForRoute, } from './route.js';
102
105
  export { useBackInterceptor } from './use-back.js';
103
- export { deriveRouteManifest, defineRoutes, mergeRouteManifests } from './route-table.js';
104
- export type { BeforeLoad, BeforeLoadArgs, LinkProps, NavLinkProps, Route, RouteContext, RouteHead, RouteHeadExport, RouteMeta, RouteManifest, RouteSpec, RouteSpecSet, ScreenTable, ModalOpenResult, OpenWindowOptions, } from './props.js';
106
+ export { deriveRouteManifest, defineRoutes, mergeRouteManifests, manifestToJson, } from './route-table.js';
107
+ export type { BeforeLoad, BeforeLoadArgs, LinkProps, NavLinkProps, Route, RouteContext, RouteHead, RouteHeadExport, RouteMeta, RouteManifest, RouteManifestJson, RouteJson, RouteDataMode, RouteNameOfPath, RouteParamsFromSpecs, RoutePathParams, RoutePresentationsFromSpecs, RouteSpec, RouteSpecSet, ManifestRouteNames, ManifestRouteParams, ManifestRoutePresentations, SpecRouteInfo, ScreenTable, ModalOpenResult, OpenWindowOptions, } from './props.js';
105
108
  export { createStore } from './store.js';
106
109
  export type { Store, ReadableStore } from './store.js';
107
110
  export { useStore } from './use-store.js';
108
111
  export { Sheet } from './Sheet.js';
109
112
  export { openSheet, closeSheet } from './sheet-service.js';
110
113
  export type { SheetProps, SheetOpenOptions, OpenSheet } from './props.js';
111
- export type { AbsoluteProps, DrawerProps, GridProps, ImageProps, LayoutChildProps, PressableProps, RichTextProps, RichTextSpanProps, RowProps, ScreenProps, SafeAreaProps, ScrollBoxProps, ScrollViewProps, SpacerProps, StackProps, SwitchProps, TabsProps, TextAreaProps, TextInputProps, TextProps, ViewProps, } from './props.js';
114
+ export type { AbsoluteProps, DrawerProps, GridProps, ImageProps, KeyboardAvoidingProps, LayoutChildProps, PressableProps, RichTextProps, RichTextSpanProps, RowProps, ScreenProps, SafeAreaProps, ScrollBoxProps, ScrollViewProps, SpacerProps, StackProps, SwitchProps, TabsProps, TextAreaProps, TextInputProps, TextProps, ViewProps, } from './props.js';
@@ -0,0 +1,114 @@
1
+ export { View } from './View.js';
2
+ export { View as Column } from './View.js';
3
+ export { Row } from './Row.js';
4
+ export { Grid } from './Grid.js';
5
+ export { Stack } from './Stack.js';
6
+ export { Absolute } from './Absolute.js';
7
+ export type { PanEvent, SwipeEvent, SetTranslate } from './props.js';
8
+ export { setTranslate } from './translate.web.js';
9
+ export { Spacer } from './Spacer.js';
10
+ export { Text } from './Text.js';
11
+ export { Markdown, MarkdownScreen } from './Markdown.js';
12
+ export type { MdDoc, MdNode, MdInline } from './Markdown.js';
13
+ export { RichText, RichTextSpan } from './RichText.js';
14
+ export { Pressable } from './Pressable.js';
15
+ export { Button } from './Button.js';
16
+ export { Collapsible } from './Collapsible.js';
17
+ export { Accordion } from './Accordion.js';
18
+ export { Checkbox } from './Checkbox.js';
19
+ export { RadioGroup } from './RadioGroup.js';
20
+ export { DropdownMenu } from './DropdownMenu.js';
21
+ export { ContextMenu } from './ContextMenu.js';
22
+ export { Badge } from './Badge.js';
23
+ export { Separator } from './Separator.js';
24
+ export { Skeleton } from './Skeleton.js';
25
+ export { Avatar } from './Avatar.js';
26
+ export { AvatarGroup } from './AvatarGroup.js';
27
+ export type { AccordionItemSpec, AccordionProps, AvatarGroupProps, AvatarProps, BadgeProps, ButtonProps, CheckboxProps, CollapsibleProps, ContextMenuProps, DropdownMenuProps, MenuItem, RadioGroupProps, RadioOption, SegmentedControlProps, SeparatorProps, SkeletonProps, } from './props.js';
28
+ export { FormField } from './FormField.js';
29
+ export { FieldGroup } from './FieldGroup.js';
30
+ export { ListItem } from './ListItem.js';
31
+ export { InputNumber } from './InputNumber.js';
32
+ export { PinInput } from './PinInput.js';
33
+ export { Select } from './Select.js';
34
+ export { SelectMenu, Combobox, InputMenu } from './aliases.js';
35
+ export { InputTags } from './InputTags.js';
36
+ export { InputRating } from './InputRating.js';
37
+ export { CheckboxGroup } from './CheckboxGroup.js';
38
+ export type { CheckboxGroupProps, FieldGroupProps, ListItemComponent, ListItemProps, ListItemSlotProps, FormFieldProps, InputNumberProps, InputRatingProps, InputTagsProps, PinInputProps, SelectOption, SelectProps, } from './props.js';
39
+ export { Breadcrumb } from './Breadcrumb.js';
40
+ export { Pagination } from './Pagination.js';
41
+ export { Stepper } from './Stepper.js';
42
+ export { NavigationMenu } from './NavigationMenu.js';
43
+ export { CommandPalette } from './CommandPalette.js';
44
+ export type { BreadcrumbItem, BreadcrumbProps, CommandPaletteProps, NavigationMenuItem, NavigationMenuProps, PaginationProps, StepperProps, StepperStep, } from './props.js';
45
+ export { Table } from './Table.js';
46
+ export { Timeline } from './Timeline.js';
47
+ export { Tree } from './Tree.js';
48
+ export { Alert } from './Alert.js';
49
+ export { Card } from './Card.js';
50
+ export { Chip } from './Chip.js';
51
+ export { Kbd } from './Kbd.js';
52
+ export { Empty } from './Empty.js';
53
+ export { Banner } from './Banner.js';
54
+ export { User } from './User.js';
55
+ export { ProgressGroup } from './ProgressGroup.js';
56
+ export type { AlertProps, BannerProps, CardProps, ChipProps, EmptyProps, KbdProps, ProgressGroupProps, TableColumn, TableProps, TimelineItem, TimelineProps, TreeNode, TreeProps, UserProps, } from './props.js';
57
+ export { Link } from './Link.js';
58
+ export { NavLink } from './NavLink.js';
59
+ export { TextInput } from './TextInput.js';
60
+ export { TextArea } from './TextArea.js';
61
+ export { SearchInput } from './SearchInput.js';
62
+ export { SegmentedControl } from './SegmentedControl.js';
63
+ export { ScrollBox } from './ScrollBox.js';
64
+ export { ScrollView } from './ScrollView.js';
65
+ export { VirtualList } from './VirtualList.js';
66
+ export type { VirtualListProps } from './props.js';
67
+ export { Image } from './Image.js';
68
+ export { WebView } from './WebView.js';
69
+ export type { WebViewContentSize, WebViewHandle, WebViewLoadEvent, WebViewProps } from './props.js';
70
+ export { Overlay } from './Overlay.js';
71
+ export { Popover } from './Popover.js';
72
+ export { Hoverable } from './Hoverable.js';
73
+ export { Tooltip } from './Tooltip.js';
74
+ export { showToast } from './toast-anchor.js';
75
+ export type { HoverableProps, OverlayProps, PopoverAnchorRef, PopoverProps, PopoverPlacement, ToastContent, ToastOptions, ToastPosition, TooltipProps, } from './props.js';
76
+ export { useAnimation } from './anim.js';
77
+ export type { AnimatedValue } from './anim.js';
78
+ export { useThemeScheme, getThemeScheme, setThemePreference, getThemePreference, themeSchemeClasses, onThemeSchemeChange, applyThemeClasses, } from './theme/theme-scheme.js';
79
+ export { useColorScheme, getColorScheme } from './theme/colorScheme.web.js';
80
+ export type { ColorScheme } from './theme/colorScheme.web.js';
81
+ export { styled } from './styled.js';
82
+ export { openWindow } from './windows.web.js';
83
+ export { Screen } from './Screen.js';
84
+ export { Tabs } from './Tabs.js';
85
+ export type { TabSpec } from './Tabs.js';
86
+ export { Switch } from './Switch.js';
87
+ export { SafeArea } from './SafeArea.js';
88
+ export { KeyboardAvoiding } from './KeyboardAvoiding.js';
89
+ export { Drawer } from './Drawer.js';
90
+ export { useSafeAreaInsets } from './safeAreaInsets.js';
91
+ export type { SafeAreaInsets } from './safeAreaInsets.js';
92
+ export { useMeasure } from './useMeasure.js';
93
+ export type { MeasureBounds, MeasureResult, UseMeasureOptions } from './props.js';
94
+ export { ActivityIndicator } from './ActivityIndicator.js';
95
+ export { Meter } from './Meter.js';
96
+ export { Slider } from './Slider.js';
97
+ export { Icon } from './Icon.js';
98
+ export { Heading } from './Heading.js';
99
+ export { registerIcon, registerIcons } from './icons.js';
100
+ export type { IconGlyph } from './icons.js';
101
+ export type { ActivityIndicatorProps, HeadingProps, IconProps, MeterProps, RefreshProps, SearchInputProps, SliderProps, } from './props.js';
102
+ export { isNative } from './platform.web.js';
103
+ export { registerStack, getStack, stackEntries } from './stacks.web.js';
104
+ export { pushRoute, popRoute, routeStacks, pushDeepLink, routeFor, currentRoute, currentModalRoute, canGoBack, useCanGoBack, useRoute, useModalRoute, redirect, addBackInterceptor, registerScreens, registerRoutes, addRoutes, screenFor, hrefFor, layoutsForRoute, } from './route.web.js';
105
+ export { useBackInterceptor } from './use-back.js';
106
+ export { deriveRouteManifest, defineRoutes, mergeRouteManifests, manifestToJson, } from './route-table.js';
107
+ export type { BeforeLoad, BeforeLoadArgs, LinkProps, NavLinkProps, Route, RouteContext, RouteHead, RouteHeadExport, RouteMeta, RouteManifest, RouteManifestJson, RouteJson, RouteDataMode, RouteNameOfPath, RouteParamsFromSpecs, RoutePathParams, RoutePresentationsFromSpecs, RouteSpec, RouteSpecSet, ManifestRouteNames, ManifestRouteParams, ManifestRoutePresentations, SpecRouteInfo, ScreenTable, ModalOpenResult, OpenWindowOptions, } from './props.js';
108
+ export { createStore } from './store.js';
109
+ export type { Store, ReadableStore } from './store.js';
110
+ export { useStore } from './use-store.js';
111
+ export { Sheet } from './Sheet.js';
112
+ export { openSheet, closeSheet } from './sheet-service.web.js';
113
+ export type { SheetProps, SheetOpenOptions, OpenSheet } from './props.js';
114
+ export type { AbsoluteProps, DrawerProps, GridProps, ImageProps, KeyboardAvoidingProps, LayoutChildProps, PressableProps, RichTextProps, RichTextSpanProps, RowProps, ScreenProps, SafeAreaProps, ScrollBoxProps, ScrollViewProps, SpacerProps, StackProps, SwitchProps, TabsProps, TextAreaProps, TextInputProps, TextProps, ViewProps, } from './props.js';
@@ -1 +1 @@
1
- export * from './index.shared.js';
1
+ export * from './index.shared.web.js';
@@ -0,0 +1,3 @@
1
+ /** Own keyboard focus only for a modal body portal. Inert preserves the
2
+ * background's state while hiding it from both focus and the browser AX tree. */
3
+ export declare function isolateModalFocus(layer: HTMLElement, panel: HTMLElement, dismiss: () => void): () => void;
@@ -0,0 +1,10 @@
1
+ /** A redirect shares its request with the original stack. Claiming another
2
+ * stack supersedes its pending navigation without reviving a stale request. */
3
+ export interface NavigationRequest {
4
+ isCurrent(): boolean;
5
+ claim(stack: string): boolean;
6
+ }
7
+ export declare function createNavigationRequests(): {
8
+ invalidate: (stack: string) => number;
9
+ begin(stack: string): NavigationRequest;
10
+ };
@@ -0,0 +1,10 @@
1
+ import type { GridLayout, RootLayout, RootLayoutOptions } from '@nativescript/core';
2
+ /** Own the resources of one independently mounted overlay. RootLayout emits
3
+ * closed before removing the host, so that notification must never reenter close. */
4
+ export declare function createOverlayLifetime(owner: RootLayout, host: GridLayout, root: {
5
+ unmount(): void;
6
+ }, label: string, onFinish: (dismissed: boolean) => void): {
7
+ own(cleanup: () => void): void;
8
+ close(): void;
9
+ open(options?: RootLayoutOptions, afterOpen?: () => void | Promise<void>): void;
10
+ };