@orz/ui 0.0.0-stage → 0.1.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 (270) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +541 -2
  3. package/dist/components/avatar.d.ts +14 -0
  4. package/dist/components/avatar.d.ts.map +1 -0
  5. package/dist/components/avatar.js +23 -0
  6. package/dist/components/avatar.js.map +1 -0
  7. package/dist/components/badge.d.ts +10 -0
  8. package/dist/components/badge.d.ts.map +1 -0
  9. package/dist/components/badge.js +26 -0
  10. package/dist/components/badge.js.map +1 -0
  11. package/dist/components/button.d.ts +11 -0
  12. package/dist/components/button.d.ts.map +1 -0
  13. package/dist/components/button.js +40 -0
  14. package/dist/components/button.js.map +1 -0
  15. package/dist/components/card.d.ts +12 -0
  16. package/dist/components/card.d.ts.map +1 -0
  17. package/dist/components/card.js +25 -0
  18. package/dist/components/card.js.map +1 -0
  19. package/dist/components/color-picker.d.ts +58 -0
  20. package/dist/components/color-picker.d.ts.map +1 -0
  21. package/dist/components/color-picker.js +950 -0
  22. package/dist/components/color-picker.js.map +1 -0
  23. package/dist/components/confirm-dialog.d.ts +26 -0
  24. package/dist/components/confirm-dialog.d.ts.map +1 -0
  25. package/dist/components/confirm-dialog.js +18 -0
  26. package/dist/components/confirm-dialog.js.map +1 -0
  27. package/dist/components/dialog.d.ts +26 -0
  28. package/dist/components/dialog.d.ts.map +1 -0
  29. package/dist/components/dialog.js +149 -0
  30. package/dist/components/dialog.js.map +1 -0
  31. package/dist/components/dropdown-menu.d.ts +30 -0
  32. package/dist/components/dropdown-menu.d.ts.map +1 -0
  33. package/dist/components/dropdown-menu.js +100 -0
  34. package/dist/components/dropdown-menu.js.map +1 -0
  35. package/dist/components/filter-menu.d.ts +98 -0
  36. package/dist/components/filter-menu.d.ts.map +1 -0
  37. package/dist/components/filter-menu.js +745 -0
  38. package/dist/components/filter-menu.js.map +1 -0
  39. package/dist/components/highlighted-input.d.ts +40 -0
  40. package/dist/components/highlighted-input.d.ts.map +1 -0
  41. package/dist/components/highlighted-input.js +95 -0
  42. package/dist/components/highlighted-input.js.map +1 -0
  43. package/dist/components/hover-card.d.ts +7 -0
  44. package/dist/components/hover-card.d.ts.map +1 -0
  45. package/dist/components/hover-card.js +22 -0
  46. package/dist/components/hover-card.js.map +1 -0
  47. package/dist/components/input.d.ts +4 -0
  48. package/dist/components/input.d.ts.map +1 -0
  49. package/dist/components/input.js +7 -0
  50. package/dist/components/input.js.map +1 -0
  51. package/dist/components/label.d.ts +5 -0
  52. package/dist/components/label.d.ts.map +1 -0
  53. package/dist/components/label.js +8 -0
  54. package/dist/components/label.js.map +1 -0
  55. package/dist/components/link-chip.d.ts +67 -0
  56. package/dist/components/link-chip.d.ts.map +1 -0
  57. package/dist/components/link-chip.js +71 -0
  58. package/dist/components/link-chip.js.map +1 -0
  59. package/dist/components/load-failure.d.ts +24 -0
  60. package/dist/components/load-failure.d.ts.map +1 -0
  61. package/dist/components/load-failure.js +27 -0
  62. package/dist/components/load-failure.js.map +1 -0
  63. package/dist/components/load-more.d.ts +15 -0
  64. package/dist/components/load-more.d.ts.map +1 -0
  65. package/dist/components/load-more.js +25 -0
  66. package/dist/components/load-more.js.map +1 -0
  67. package/dist/components/media-controls.d.ts +50 -0
  68. package/dist/components/media-controls.d.ts.map +1 -0
  69. package/dist/components/media-controls.js +71 -0
  70. package/dist/components/media-controls.js.map +1 -0
  71. package/dist/components/popover.d.ts +9 -0
  72. package/dist/components/popover.d.ts.map +1 -0
  73. package/dist/components/popover.js +82 -0
  74. package/dist/components/popover.js.map +1 -0
  75. package/dist/components/query-box.d.ts +78 -0
  76. package/dist/components/query-box.d.ts.map +1 -0
  77. package/dist/components/query-box.js +332 -0
  78. package/dist/components/query-box.js.map +1 -0
  79. package/dist/components/query-highlight.d.ts +14 -0
  80. package/dist/components/query-highlight.d.ts.map +1 -0
  81. package/dist/components/query-highlight.js +132 -0
  82. package/dist/components/query-highlight.js.map +1 -0
  83. package/dist/components/select.d.ts +19 -0
  84. package/dist/components/select.d.ts.map +1 -0
  85. package/dist/components/select.js +38 -0
  86. package/dist/components/select.js.map +1 -0
  87. package/dist/components/separator.d.ts +5 -0
  88. package/dist/components/separator.d.ts.map +1 -0
  89. package/dist/components/separator.js +9 -0
  90. package/dist/components/separator.js.map +1 -0
  91. package/dist/components/sheet.d.ts +16 -0
  92. package/dist/components/sheet.d.ts.map +1 -0
  93. package/dist/components/sheet.js +41 -0
  94. package/dist/components/sheet.js.map +1 -0
  95. package/dist/components/skeleton.d.ts +3 -0
  96. package/dist/components/skeleton.d.ts.map +1 -0
  97. package/dist/components/skeleton.js +7 -0
  98. package/dist/components/skeleton.js.map +1 -0
  99. package/dist/components/slider.d.ts +8 -0
  100. package/dist/components/slider.d.ts.map +1 -0
  101. package/dist/components/slider.js +14 -0
  102. package/dist/components/slider.js.map +1 -0
  103. package/dist/components/sonner.d.ts +4 -0
  104. package/dist/components/sonner.d.ts.map +1 -0
  105. package/dist/components/sonner.js +26 -0
  106. package/dist/components/sonner.js.map +1 -0
  107. package/dist/components/switch.d.ts +5 -0
  108. package/dist/components/switch.d.ts.map +1 -0
  109. package/dist/components/switch.js +8 -0
  110. package/dist/components/switch.js.map +1 -0
  111. package/dist/components/table.d.ts +11 -0
  112. package/dist/components/table.d.ts.map +1 -0
  113. package/dist/components/table.js +28 -0
  114. package/dist/components/table.js.map +1 -0
  115. package/dist/components/tabs.d.ts +8 -0
  116. package/dist/components/tabs.d.ts.map +1 -0
  117. package/dist/components/tabs.js +18 -0
  118. package/dist/components/tabs.js.map +1 -0
  119. package/dist/components/textarea.d.ts +4 -0
  120. package/dist/components/textarea.d.ts.map +1 -0
  121. package/dist/components/textarea.js +7 -0
  122. package/dist/components/textarea.js.map +1 -0
  123. package/dist/components/theme-editor/draft.d.ts +235 -0
  124. package/dist/components/theme-editor/draft.d.ts.map +1 -0
  125. package/dist/components/theme-editor/draft.js +638 -0
  126. package/dist/components/theme-editor/draft.js.map +1 -0
  127. package/dist/components/theme-editor/export-panel.d.ts +14 -0
  128. package/dist/components/theme-editor/export-panel.d.ts.map +1 -0
  129. package/dist/components/theme-editor/export-panel.js +39 -0
  130. package/dist/components/theme-editor/export-panel.js.map +1 -0
  131. package/dist/components/theme-editor/form.d.ts +69 -0
  132. package/dist/components/theme-editor/form.d.ts.map +1 -0
  133. package/dist/components/theme-editor/form.js +350 -0
  134. package/dist/components/theme-editor/form.js.map +1 -0
  135. package/dist/components/theme-editor/import-panel.d.ts +21 -0
  136. package/dist/components/theme-editor/import-panel.d.ts.map +1 -0
  137. package/dist/components/theme-editor/import-panel.js +117 -0
  138. package/dist/components/theme-editor/import-panel.js.map +1 -0
  139. package/dist/components/theme-editor/theme-list.d.ts +23 -0
  140. package/dist/components/theme-editor/theme-list.d.ts.map +1 -0
  141. package/dist/components/theme-editor/theme-list.js +42 -0
  142. package/dist/components/theme-editor/theme-list.js.map +1 -0
  143. package/dist/components/theme-editor/token-list.d.ts +30 -0
  144. package/dist/components/theme-editor/token-list.d.ts.map +1 -0
  145. package/dist/components/theme-editor/token-list.js +124 -0
  146. package/dist/components/theme-editor/token-list.js.map +1 -0
  147. package/dist/components/theme-editor/tokens.d.ts +37 -0
  148. package/dist/components/theme-editor/tokens.d.ts.map +1 -0
  149. package/dist/components/theme-editor/tokens.js +155 -0
  150. package/dist/components/theme-editor/tokens.js.map +1 -0
  151. package/dist/components/theme-editor.d.ts +26 -0
  152. package/dist/components/theme-editor.d.ts.map +1 -0
  153. package/dist/components/theme-editor.js +467 -0
  154. package/dist/components/theme-editor.js.map +1 -0
  155. package/dist/components/theme-menu.d.ts +28 -0
  156. package/dist/components/theme-menu.d.ts.map +1 -0
  157. package/dist/components/theme-menu.js +308 -0
  158. package/dist/components/theme-menu.js.map +1 -0
  159. package/dist/components/tooltip.d.ts +11 -0
  160. package/dist/components/tooltip.d.ts.map +1 -0
  161. package/dist/components/tooltip.js +18 -0
  162. package/dist/components/tooltip.js.map +1 -0
  163. package/dist/components/unsaved-changes-dialog.d.ts +39 -0
  164. package/dist/components/unsaved-changes-dialog.d.ts.map +1 -0
  165. package/dist/components/unsaved-changes-dialog.js +46 -0
  166. package/dist/components/unsaved-changes-dialog.js.map +1 -0
  167. package/dist/hooks/scroll-insets.d.ts +89 -0
  168. package/dist/hooks/scroll-insets.d.ts.map +1 -0
  169. package/dist/hooks/scroll-insets.js +265 -0
  170. package/dist/hooks/scroll-insets.js.map +1 -0
  171. package/dist/hooks/use-element-height.d.ts +11 -0
  172. package/dist/hooks/use-element-height.d.ts.map +1 -0
  173. package/dist/hooks/use-element-height.js +33 -0
  174. package/dist/hooks/use-element-height.js.map +1 -0
  175. package/dist/hooks/use-media-query.d.ts +22 -0
  176. package/dist/hooks/use-media-query.d.ts.map +1 -0
  177. package/dist/hooks/use-media-query.js +38 -0
  178. package/dist/hooks/use-media-query.js.map +1 -0
  179. package/dist/hooks/use-overlay-scrollbars.d.ts +31 -0
  180. package/dist/hooks/use-overlay-scrollbars.d.ts.map +1 -0
  181. package/dist/hooks/use-overlay-scrollbars.js +80 -0
  182. package/dist/hooks/use-overlay-scrollbars.js.map +1 -0
  183. package/dist/hooks/use-paged-append.d.ts +7 -0
  184. package/dist/hooks/use-paged-append.d.ts.map +1 -0
  185. package/dist/hooks/use-paged-append.js +53 -0
  186. package/dist/hooks/use-paged-append.js.map +1 -0
  187. package/dist/hooks/use-query-completion.d.ts +27 -0
  188. package/dist/hooks/use-query-completion.d.ts.map +1 -0
  189. package/dist/hooks/use-query-completion.js +100 -0
  190. package/dist/hooks/use-query-completion.js.map +1 -0
  191. package/dist/hooks/use-slash-shortcut.d.ts +9 -0
  192. package/dist/hooks/use-slash-shortcut.d.ts.map +1 -0
  193. package/dist/hooks/use-slash-shortcut.js +38 -0
  194. package/dist/hooks/use-slash-shortcut.js.map +1 -0
  195. package/dist/hooks/viewport-chrome.d.ts +50 -0
  196. package/dist/hooks/viewport-chrome.d.ts.map +1 -0
  197. package/dist/hooks/viewport-chrome.js +170 -0
  198. package/dist/hooks/viewport-chrome.js.map +1 -0
  199. package/dist/index.d.ts +2 -0
  200. package/dist/index.d.ts.map +1 -0
  201. package/dist/index.js +2 -0
  202. package/dist/index.js.map +1 -0
  203. package/dist/lib/cell-width-table.d.ts +3 -0
  204. package/dist/lib/cell-width-table.d.ts.map +1 -0
  205. package/dist/lib/cell-width-table.js +6 -0
  206. package/dist/lib/cell-width-table.js.map +1 -0
  207. package/dist/lib/cell-width.d.ts +7 -0
  208. package/dist/lib/cell-width.d.ts.map +1 -0
  209. package/dist/lib/cell-width.js +50 -0
  210. package/dist/lib/cell-width.js.map +1 -0
  211. package/dist/lib/clipboard.d.ts +8 -0
  212. package/dist/lib/clipboard.d.ts.map +1 -0
  213. package/dist/lib/clipboard.js +19 -0
  214. package/dist/lib/clipboard.js.map +1 -0
  215. package/dist/lib/color.d.ts +40 -0
  216. package/dist/lib/color.d.ts.map +1 -0
  217. package/dist/lib/color.js +177 -0
  218. package/dist/lib/color.js.map +1 -0
  219. package/dist/lib/scroll-map.d.ts +20 -0
  220. package/dist/lib/scroll-map.d.ts.map +1 -0
  221. package/dist/lib/scroll-map.js +46 -0
  222. package/dist/lib/scroll-map.js.map +1 -0
  223. package/dist/lib/text-metrics.d.ts +33 -0
  224. package/dist/lib/text-metrics.d.ts.map +1 -0
  225. package/dist/lib/text-metrics.js +89 -0
  226. package/dist/lib/text-metrics.js.map +1 -0
  227. package/dist/lib/theme-file.d.ts +51 -0
  228. package/dist/lib/theme-file.d.ts.map +1 -0
  229. package/dist/lib/theme-file.js +511 -0
  230. package/dist/lib/theme-file.js.map +1 -0
  231. package/dist/lib/unsaved-guard.d.ts +33 -0
  232. package/dist/lib/unsaved-guard.d.ts.map +1 -0
  233. package/dist/lib/unsaved-guard.js +37 -0
  234. package/dist/lib/unsaved-guard.js.map +1 -0
  235. package/dist/lib/utils.d.ts +3 -0
  236. package/dist/lib/utils.d.ts.map +1 -0
  237. package/dist/lib/utils.js +6 -0
  238. package/dist/lib/utils.js.map +1 -0
  239. package/dist/theme/custom.d.ts +8 -0
  240. package/dist/theme/custom.d.ts.map +1 -0
  241. package/dist/theme/custom.js +56 -0
  242. package/dist/theme/custom.js.map +1 -0
  243. package/dist/theme/index.d.ts +6 -0
  244. package/dist/theme/index.d.ts.map +1 -0
  245. package/dist/theme/index.js +5 -0
  246. package/dist/theme/index.js.map +1 -0
  247. package/dist/theme/paint-guard.d.ts +20 -0
  248. package/dist/theme/paint-guard.d.ts.map +1 -0
  249. package/dist/theme/paint-guard.js +120 -0
  250. package/dist/theme/paint-guard.js.map +1 -0
  251. package/dist/theme/picks.d.ts +22 -0
  252. package/dist/theme/picks.d.ts.map +1 -0
  253. package/dist/theme/picks.js +43 -0
  254. package/dist/theme/picks.js.map +1 -0
  255. package/dist/theme/pref.d.ts +39 -0
  256. package/dist/theme/pref.d.ts.map +1 -0
  257. package/dist/theme/pref.js +129 -0
  258. package/dist/theme/pref.js.map +1 -0
  259. package/dist/theme/provider.d.ts +41 -0
  260. package/dist/theme/provider.d.ts.map +1 -0
  261. package/dist/theme/provider.js +103 -0
  262. package/dist/theme/provider.js.map +1 -0
  263. package/dist/theme/store.d.ts +104 -0
  264. package/dist/theme/store.d.ts.map +1 -0
  265. package/dist/theme/store.js +509 -0
  266. package/dist/theme/store.js.map +1 -0
  267. package/package.json +94 -3
  268. package/styles.css +79 -0
  269. package/theme.css +186 -0
  270. package/vendor/shadcn-tailwind.css +664 -0
@@ -0,0 +1,89 @@
1
+ import { type RefObject } from "react";
2
+ /** Page coordinates of the thing to be revealed. */
3
+ export type ScrollBlock = {
4
+ top: number;
5
+ height: number;
6
+ };
7
+ /** Viewport coordinates of the strip no overlay covers. */
8
+ export type UsableViewport = {
9
+ top: number;
10
+ height: number;
11
+ };
12
+ /**
13
+ * `"auto"` centres a block that fits and tops-aligns one that does not;
14
+ * `"start"` demands the top edge even when the block would fit, which is what
15
+ * a file diff wants — its path header under the toolbar (T-190 §5).
16
+ */
17
+ export type RevealMode = "auto" | "start";
18
+ /** Which `scrollIntoView` alignment reveals as much of `block` as it can. */
19
+ export declare function blockFor(block: ScrollBlock, usable: UsableViewport, mode?: RevealMode): ScrollLogicalPosition;
20
+ /**
21
+ * Where the page comes to rest once `scrollIntoView` has placed `block`.
22
+ * ↑↓ and the counter read this instead of performing the scroll, so the number
23
+ * on screen cannot disagree with where the arrow lands (T-61).
24
+ */
25
+ export declare function restingScrollY(block: ScrollBlock, usable: UsableViewport, mode?: RevealMode): number;
26
+ /**
27
+ * Read back off `<html>` rather than passed down: the calls that land a target
28
+ * sit deep inside components that know nothing about the page's overlays, and
29
+ * `scroll-padding` is already the value the engine itself obeys.
30
+ */
31
+ export declare function usableViewport(): UsableViewport;
32
+ /**
33
+ * Open every closed `<details>` between `el` and the document root.
34
+ *
35
+ * A target inside a shut fold has no box at all, so `scrollIntoView` on it
36
+ * does nothing and reports nothing.
37
+ */
38
+ export declare function openEnclosingFolds(el: Element): void;
39
+ /**
40
+ * Bring `el` into the strip no overlay covers, and flash it. The one landing
41
+ * out of which every anchor, ↑↓ step and per-file jump is served.
42
+ */
43
+ export declare function revealBlock(el: HTMLElement, { mode, behavior, flash: highlight, }?: {
44
+ mode?: RevealMode;
45
+ behavior?: ScrollBehavior;
46
+ flash?: boolean;
47
+ }): void;
48
+ /**
49
+ * Whether an untouched reader is being held on a particular element, as
50
+ * opposed to the end of the document or nothing at all. Following a new item
51
+ * at the end should not take the reader off a target they were sent to.
52
+ */
53
+ export declare function isHoldingTarget(): boolean;
54
+ /**
55
+ * Hold `el` where `revealBlock` put it, re-revealing it without the flash
56
+ * every time `container` resizes; see `hold`.
57
+ */
58
+ export declare function holdRevealed(el: HTMLElement, container: Element, mode?: RevealMode, behavior?: ScrollBehavior): () => void;
59
+ /** Go to the end of the document and stay there; see `hold`. */
60
+ export declare function landAtBottom(): () => void;
61
+ /**
62
+ * Keep the release of the last hold this component started, and call it on
63
+ * unmount: a page left without input would otherwise go on being held.
64
+ */
65
+ export declare function useOwnHold(): (release: () => void) => void;
66
+ export type ScrollInsetSources = {
67
+ /** Overlays pinned to the viewport's top edge, a fixed app header included. */
68
+ top?: ReadonlyArray<RefObject<HTMLElement | null>>;
69
+ bottom?: ReadonlyArray<RefObject<HTMLElement | null>>;
70
+ };
71
+ /**
72
+ * Declare this page's overlays, so every `scrollIntoView` on it lands clear of
73
+ * them.
74
+ *
75
+ * `useLayoutEffect`, not `useEffect`: an anchor that scrolls from a passive
76
+ * effect in a child runs before any passive effect here, and a one-shot guard
77
+ * there never offers a second chance. Layout effects run ahead of the whole
78
+ * passive pass, so the insets are always in place first.
79
+ *
80
+ * The elements are measured directly rather than through `useElementHeight`,
81
+ * whose state holds a fallback for one commit — 56 against a real 93 on a
82
+ * narrow screen, exactly across the frame a hard refresh lands in.
83
+ *
84
+ * No overlay is added implicitly: a fixed header is one more ref in `top`.
85
+ * What an on-screen keyboard covers is counted on its own, from the visual
86
+ * viewport. The landing flash is `.anchor-flash` from `@orz/ui/styles.css`.
87
+ */
88
+ export declare function useScrollInsets({ top, bottom, }: ScrollInsetSources): void;
89
+ //# sourceMappingURL=scroll-insets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-insets.d.ts","sourceRoot":"","sources":["../../src/hooks/scroll-insets.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAMf,oDAAoD;AACpD,MAAM,MAAM,WAAW,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAK1C,6EAA6E;AAC7E,wBAAgB,QAAQ,CACtB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE,UAAmB,GACxB,qBAAqB,CAMvB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE,UAAmB,GACxB,MAAM,CAGR;AAQD;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAK/C;AAeD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAOpD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,WAAW,EACf,EACE,IAAa,EACb,QAAQ,EACR,KAAK,EAAE,SAAgB,GACxB,GAAE;IACD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,GACL,IAAI,CAUN;AAQD;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAyCD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE,UAAmB,EACzB,QAAQ,CAAC,EAAE,cAAc,GACxB,MAAM,IAAI,CAMZ;AAcD,gEAAgE;AAChE,wBAAgB,YAAY,IAAI,MAAM,IAAI,CAGzC;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAO1D;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+EAA+E;IAC/E,GAAG,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;CACvD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAQ,EACR,MAAW,GACZ,EAAE,kBAAkB,GAAG,IAAI,CAoF3B"}
@@ -0,0 +1,265 @@
1
+ import { useCallback, useEffect, useLayoutEffect, useRef, } from "react";
2
+ import { VIEWPORT_CHROME_EVENT, visualViewportInsets, } from "./viewport-chrome.js";
3
+ /** Gap between an overlay's edge and whatever lands against it. */
4
+ const BREATHING_ROOM = 8;
5
+ /** Which `scrollIntoView` alignment reveals as much of `block` as it can. */
6
+ export function blockFor(block, usable, mode = "auto") {
7
+ if (mode === "start")
8
+ return "start";
9
+ // Overlays can leave nothing over — a long draft in the composer takes the
10
+ // strip past zero — and centring in a negative strip aims above its own top.
11
+ if (usable.height <= 0)
12
+ return "start";
13
+ return block.height <= usable.height ? "center" : "start";
14
+ }
15
+ /**
16
+ * Where the page comes to rest once `scrollIntoView` has placed `block`.
17
+ * ↑↓ and the counter read this instead of performing the scroll, so the number
18
+ * on screen cannot disagree with where the arrow lands (T-61).
19
+ */
20
+ export function restingScrollY(block, usable, mode = "auto") {
21
+ if (blockFor(block, usable, mode) === "start")
22
+ return block.top - usable.top;
23
+ return block.top + block.height / 2 - (usable.top + usable.height / 2);
24
+ }
25
+ /** `auto` and anything unparseable both mean "no overlay on that edge". */
26
+ function pixelsOf(value) {
27
+ const parsed = Number.parseFloat(value);
28
+ return Number.isFinite(parsed) ? parsed : 0;
29
+ }
30
+ /**
31
+ * Read back off `<html>` rather than passed down: the calls that land a target
32
+ * sit deep inside components that know nothing about the page's overlays, and
33
+ * `scroll-padding` is already the value the engine itself obeys.
34
+ */
35
+ export function usableViewport() {
36
+ const style = getComputedStyle(document.documentElement);
37
+ const top = pixelsOf(style.scrollPaddingTop);
38
+ const bottom = pixelsOf(style.scrollPaddingBottom);
39
+ return { top, height: window.innerHeight - top - bottom };
40
+ }
41
+ /** One-shot highlight; restartable when the same target is revealed again. */
42
+ function flash(el) {
43
+ el.classList.remove("anchor-flash");
44
+ // Reflow so removing+adding the class restarts the animation.
45
+ void el.offsetWidth;
46
+ el.classList.add("anchor-flash");
47
+ el.addEventListener("animationend", () => el.classList.remove("anchor-flash"), { once: true });
48
+ }
49
+ /**
50
+ * Open every closed `<details>` between `el` and the document root.
51
+ *
52
+ * A target inside a shut fold has no box at all, so `scrollIntoView` on it
53
+ * does nothing and reports nothing.
54
+ */
55
+ export function openEnclosingFolds(el) {
56
+ for (let from = el.parentElement; from !== null;) {
57
+ const fold = from.closest("details:not([open])");
58
+ if (fold === null)
59
+ return;
60
+ fold.setAttribute("open", "");
61
+ from = fold.parentElement;
62
+ }
63
+ }
64
+ /**
65
+ * Bring `el` into the strip no overlay covers, and flash it. The one landing
66
+ * out of which every anchor, ↑↓ step and per-file jump is served.
67
+ */
68
+ export function revealBlock(el, { mode = "auto", behavior, flash: highlight = true, } = {}) {
69
+ openEnclosingFolds(el);
70
+ const rect = el.getBoundingClientRect();
71
+ const block = blockFor({ top: rect.top + window.scrollY, height: rect.height }, usableViewport(), mode);
72
+ el.scrollIntoView({ block, behavior });
73
+ if (highlight)
74
+ flash(el);
75
+ }
76
+ /**
77
+ * The page's one hold. Two at once would each put the viewport back on its
78
+ * own target at every resize, so a newer landing retires the older one.
79
+ */
80
+ let held = null;
81
+ /**
82
+ * Whether an untouched reader is being held on a particular element, as
83
+ * opposed to the end of the document or nothing at all. Following a new item
84
+ * at the end should not take the reader off a target they were sent to.
85
+ */
86
+ export function isHoldingTarget() {
87
+ return held !== null && !held.onEnd;
88
+ }
89
+ /**
90
+ * Run `place` again every time `container` resizes, until the reader's first
91
+ * input. Returns the release, for when the landing stops mattering first.
92
+ *
93
+ * A landing is made against the page as it stands, and the page keeps
94
+ * arriving after it: images, diffs, attachment lists, each pushing the target
95
+ * away from where it was put. After the first input, re-placing would fight
96
+ * the reader. There is no settle timeout: late content lands with unbounded
97
+ * gaps, and a timer that fires inside one re-opens the race.
98
+ *
99
+ * Dragging the scrollbar counts as input: Chromium and Firefox both deliver
100
+ * its `pointerdown` to `<html>`.
101
+ */
102
+ function hold(container, place, onEnd = false) {
103
+ held?.release();
104
+ if (typeof ResizeObserver === "undefined")
105
+ return () => { }; // happy-dom
106
+ const controller = new AbortController();
107
+ const observer = new ResizeObserver(() => place(release));
108
+ const release = () => {
109
+ observer.disconnect();
110
+ controller.abort();
111
+ if (held?.release === release)
112
+ held = null;
113
+ };
114
+ observer.observe(container);
115
+ for (const type of ["wheel", "touchstart", "pointerdown", "keydown"]) {
116
+ window.addEventListener(type, release, {
117
+ capture: true,
118
+ passive: true,
119
+ signal: controller.signal,
120
+ });
121
+ }
122
+ held = { release, onEnd };
123
+ return release;
124
+ }
125
+ /**
126
+ * Hold `el` where `revealBlock` put it, re-revealing it without the flash
127
+ * every time `container` resizes; see `hold`.
128
+ */
129
+ export function holdRevealed(el, container, mode = "auto", behavior) {
130
+ return hold(container, (release) => {
131
+ // Gone with a route change nobody touched the page for.
132
+ if (!el.isConnected)
133
+ release();
134
+ else
135
+ revealBlock(el, { mode, behavior, flash: false });
136
+ });
137
+ }
138
+ /**
139
+ * Bottom of the document, which sits below a sticky composer's in-flow spot.
140
+ *
141
+ * The largest offset there is, not `scrollHeight`: iOS Safari takes the
142
+ * overshoot literally for a frame, parking the visual viewport a whole screen
143
+ * past the end — one blank white frame on every landing.
144
+ */
145
+ function scrollToEnd() {
146
+ const root = document.documentElement;
147
+ window.scrollTo(0, Math.max(0, root.scrollHeight - root.clientHeight));
148
+ }
149
+ /** Go to the end of the document and stay there; see `hold`. */
150
+ export function landAtBottom() {
151
+ scrollToEnd();
152
+ return hold(document.body, scrollToEnd, true);
153
+ }
154
+ /**
155
+ * Keep the release of the last hold this component started, and call it on
156
+ * unmount: a page left without input would otherwise go on being held.
157
+ */
158
+ export function useOwnHold() {
159
+ const own = useRef(() => { });
160
+ useEffect(() => () => own.current(), []);
161
+ return useCallback((release) => {
162
+ own.current();
163
+ own.current = release;
164
+ }, []);
165
+ }
166
+ /**
167
+ * Declare this page's overlays, so every `scrollIntoView` on it lands clear of
168
+ * them.
169
+ *
170
+ * `useLayoutEffect`, not `useEffect`: an anchor that scrolls from a passive
171
+ * effect in a child runs before any passive effect here, and a one-shot guard
172
+ * there never offers a second chance. Layout effects run ahead of the whole
173
+ * passive pass, so the insets are always in place first.
174
+ *
175
+ * The elements are measured directly rather than through `useElementHeight`,
176
+ * whose state holds a fallback for one commit — 56 against a real 93 on a
177
+ * narrow screen, exactly across the frame a hard refresh lands in.
178
+ *
179
+ * No overlay is added implicitly: a fixed header is one more ref in `top`.
180
+ * What an on-screen keyboard covers is counted on its own, from the visual
181
+ * viewport. The landing flash is `.anchor-flash` from `@orz/ui/styles.css`.
182
+ */
183
+ export function useScrollInsets({ top = [], bottom = [], }) {
184
+ const sources = useRef({ top, bottom });
185
+ const remeasure = useRef(() => { });
186
+ useLayoutEffect(() => {
187
+ const root = document.documentElement;
188
+ const observed = new Set();
189
+ let observer = null;
190
+ const watch = (el) => {
191
+ if (observed.has(el))
192
+ return;
193
+ observed.add(el);
194
+ observer?.observe(el);
195
+ };
196
+ const measure = () => {
197
+ // A caret inside a sticky overlay always sits within that overlay's own
198
+ // inset, and Chrome's caret reveal honours scroll-padding: it scrolled
199
+ // the page on every typed character, the overlay riding along, so the
200
+ // caret was never "revealed". Nothing inside an overlay can be hidden
201
+ // behind it, so the one holding focus stops counting.
202
+ const focused = document.activeElement;
203
+ const extent = (el) => focused !== null && el.contains(focused)
204
+ ? 0
205
+ : el.getBoundingClientRect().height;
206
+ let overlays = 0;
207
+ let bottomInset = 0;
208
+ for (const el of sources.current.top.map((r) => r.current)) {
209
+ if (el === null)
210
+ continue;
211
+ overlays += extent(el);
212
+ watch(el);
213
+ }
214
+ for (const el of sources.current.bottom.map((r) => r.current)) {
215
+ if (el === null)
216
+ continue;
217
+ bottomInset += extent(el);
218
+ watch(el);
219
+ }
220
+ // A keyboard covers the layout viewport's bottom and can pan its top
221
+ // out of view; sticky edges follow it, and so must the padding, or a
222
+ // reveal would centre its target behind the keyboard. A header
223
+ // useAutoHideHeader has slid partly away covers that much less.
224
+ const edges = visualViewportInsets();
225
+ const slid = pixelsOf(root.style.getPropertyValue("--header-hide"));
226
+ const topInset = BREATHING_ROOM + edges.top + Math.max(0, overlays - slid);
227
+ bottomInset += edges.bottom;
228
+ root.style.scrollPaddingTop = `${topInset}px`;
229
+ root.style.scrollPaddingBottom = `${bottomInset}px`;
230
+ };
231
+ observer =
232
+ typeof ResizeObserver === "undefined"
233
+ ? null
234
+ : new ResizeObserver(measure);
235
+ remeasure.current = measure;
236
+ measure();
237
+ window.addEventListener("resize", measure);
238
+ window.addEventListener(VIEWPORT_CHROME_EVENT, measure);
239
+ // A keyboard opening resizes only the visual viewport, never the window.
240
+ const vv = window.visualViewport;
241
+ vv?.addEventListener("resize", measure);
242
+ vv?.addEventListener("scroll", measure);
243
+ document.addEventListener("focusin", measure);
244
+ document.addEventListener("focusout", measure);
245
+ return () => {
246
+ window.removeEventListener("resize", measure);
247
+ window.removeEventListener(VIEWPORT_CHROME_EVENT, measure);
248
+ vv?.removeEventListener("resize", measure);
249
+ vv?.removeEventListener("scroll", measure);
250
+ document.removeEventListener("focusin", measure);
251
+ document.removeEventListener("focusout", measure);
252
+ observer?.disconnect();
253
+ root.style.removeProperty("scroll-padding-top");
254
+ root.style.removeProperty("scroll-padding-bottom");
255
+ };
256
+ }, []);
257
+ // An overlay that mounts later — a composer opening, one arriving with the
258
+ // data it belongs to — had a null ref when the effect above ran, and nothing
259
+ // observes an element that does not exist yet.
260
+ useLayoutEffect(() => {
261
+ sources.current = { top, bottom };
262
+ remeasure.current();
263
+ });
264
+ }
265
+ //# sourceMappingURL=scroll-insets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-insets.js","sourceRoot":"","sources":["../../src/hooks/scroll-insets.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,SAAS,EACT,eAAe,EACf,MAAM,GACP,MAAM,OAAO,CAAC;AACf,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAe9B,mEAAmE;AACnE,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,6EAA6E;AAC7E,MAAM,UAAU,QAAQ,CACtB,KAAkB,EAClB,MAAsB,EACtB,IAAI,GAAe,MAAM;IAEzB,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACrC,2EAA2E;IAC3E,6EAA6E;IAC7E,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IACvC,OAAO,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAkB,EAClB,MAAsB,EACtB,IAAI,GAAe,MAAM;IAEzB,IAAI,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IAC7E,OAAO,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,2EAA2E;AAC3E,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACnD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;AAC5D,CAAC;AAED,8EAA8E;AAC9E,SAAS,KAAK,CAAC,EAAe;IAC5B,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACpC,8DAA8D;IAC9D,KAAK,EAAE,CAAC,WAAW,CAAC;IACpB,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACjC,EAAE,CAAC,gBAAgB,CACjB,cAAc,EACd,GAAG,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,EACzC,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAW;IAC5C,KAAK,IAAI,IAAI,GAAG,EAAE,CAAC,aAAa,EAAE,IAAI,KAAK,IAAI,GAAI,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACjD,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO;QAC1B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,EAAe,EACf,EACE,IAAI,GAAG,MAAM,EACb,QAAQ,EACR,KAAK,EAAE,SAAS,GAAG,IAAI,GACxB,GAIG,EAAE;IAEN,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACvB,MAAM,IAAI,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,QAAQ,CACpB,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EACvD,cAAc,EAAE,EAChB,IAAI,CACL,CAAC;IACF,EAAE,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvC,IAAI,SAAS;QAAE,KAAK,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,IAAI,IAAI,GAAmD,IAAI,CAAC;AAEhE;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,IAAI,CACX,SAAkB,EAClB,KAAoC,EACpC,KAAK,GAAG,KAAK;IAEb,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,IAAI,OAAO,cAAc,KAAK,WAAW;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,YAAY;IACxE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,QAAQ,CAAC,UAAU,EAAE,CAAC;QACtB,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,IAAI,EAAE,OAAO,KAAK,OAAO;YAAE,IAAI,GAAG,IAAI,CAAC;IAC7C,CAAC,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;QACrE,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE;YACrC,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;IACL,CAAC;IACD,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,EAAe,EACf,SAAkB,EAClB,IAAI,GAAe,MAAM,EACzB,QAAyB;IAEzB,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;QACjC,wDAAwD;QACxD,IAAI,CAAC,EAAE,CAAC,WAAW;YAAE,OAAO,EAAE,CAAC;;YAC1B,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW;IAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC;IACtC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,YAAY;IAC1B,WAAW,EAAE,CAAC;IACd,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,MAAM,CAAa,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACzC,OAAO,WAAW,CAAC,CAAC,OAAmB,EAAE,EAAE;QACzC,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAQD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,GAAG,GAAG,EAAE,EACR,MAAM,GAAG,EAAE,GACQ;IACnB,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,MAAM,CAAa,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAE/C,eAAe,CAAC,GAAG,EAAE;QACnB,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAW,CAAC;QACpC,IAAI,QAAQ,GAA0B,IAAI,CAAC;QAE3C,MAAM,KAAK,GAAG,CAAC,EAAW,EAAE,EAAE;YAC5B,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,OAAO;YAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjB,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,wEAAwE;YACxE,uEAAuE;YACvE,sEAAsE;YACtE,sEAAsE;YACtE,sDAAsD;YACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC;YACvC,MAAM,MAAM,GAAG,CAAC,EAAe,EAAE,EAAE,CACjC,OAAO,KAAK,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACtC,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC;YACxC,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3D,IAAI,EAAE,KAAK,IAAI;oBAAE,SAAS;gBAC1B,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC;gBACvB,KAAK,CAAC,EAAE,CAAC,CAAC;YACZ,CAAC;YACD,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9D,IAAI,EAAE,KAAK,IAAI;oBAAE,SAAS;gBAC1B,WAAW,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC1B,KAAK,CAAC,EAAE,CAAC,CAAC;YACZ,CAAC;YACD,qEAAqE;YACrE,qEAAqE;YACrE,+DAA+D;YAC/D,gEAAgE;YAChE,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC;YACpE,MAAM,QAAQ,GACZ,cAAc,GAAG,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAC;YAC5D,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,GAAG,QAAQ,IAAI,CAAC;YAC9C,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,GAAG,WAAW,IAAI,CAAC;QACtD,CAAC,CAAC;QAEF,QAAQ;YACN,OAAO,cAAc,KAAK,WAAW;gBACnC,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;QAClC,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC;QAC5B,OAAO,EAAE,CAAC;QACV,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;QACxD,yEAAyE;QACzE,MAAM,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC;QACjC,EAAE,EAAE,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACxC,EAAE,EAAE,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACxC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9C,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;YAC3D,EAAE,EAAE,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC3C,EAAE,EAAE,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC3C,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACjD,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAClD,QAAQ,EAAE,UAAU,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;YAChD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,2EAA2E;IAC3E,6EAA6E;IAC7E,+CAA+C;IAC/C,eAAe,CAAC,GAAG,EAAE;QACnB,OAAO,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAClC,SAAS,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The live height of one element, for anything that has to sit directly
3
+ * beneath it — a header that gains a second row on narrow screens has a
4
+ * height no CSS offset can name. `fallback` stands in until the first
5
+ * measurement, and for good when `target` finds nothing.
6
+ *
7
+ * `target` is asked once, after mount (`() => ref.current`, or a
8
+ * `querySelector`), so it may be a fresh closure every render.
9
+ */
10
+ export declare function useElementHeight(target: () => Element | null, fallback: number): number;
11
+ //# sourceMappingURL=use-element-height.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-element-height.d.ts","sourceRoot":"","sources":["../../src/hooks/use-element-height.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,OAAO,GAAG,IAAI,EAC5B,QAAQ,EAAE,MAAM,GACf,MAAM,CAuBR"}
@@ -0,0 +1,33 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ /**
3
+ * The live height of one element, for anything that has to sit directly
4
+ * beneath it — a header that gains a second row on narrow screens has a
5
+ * height no CSS offset can name. `fallback` stands in until the first
6
+ * measurement, and for good when `target` finds nothing.
7
+ *
8
+ * `target` is asked once, after mount (`() => ref.current`, or a
9
+ * `querySelector`), so it may be a fresh closure every render.
10
+ */
11
+ export function useElementHeight(target, fallback) {
12
+ const [height, setHeight] = useState(fallback);
13
+ const find = useRef(target);
14
+ find.current = target;
15
+ useEffect(() => {
16
+ const element = find.current();
17
+ if (element === null)
18
+ return;
19
+ const measure = () => setHeight(element.getBoundingClientRect().height);
20
+ measure();
21
+ window.addEventListener("resize", measure);
22
+ const observer = typeof ResizeObserver === "undefined"
23
+ ? null
24
+ : new ResizeObserver(measure);
25
+ observer?.observe(element);
26
+ return () => {
27
+ window.removeEventListener("resize", measure);
28
+ observer?.disconnect();
29
+ };
30
+ }, []);
31
+ return height;
32
+ }
33
+ //# sourceMappingURL=use-element-height.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-element-height.js","sourceRoot":"","sources":["../../src/hooks/use-element-height.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA4B,EAC5B,QAAgB;IAEhB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IAEtB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/B,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO;QAC7B,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC,CAAC;QACxE,OAAO,EAAE,CAAC;QACV,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,QAAQ,GACZ,OAAO,cAAc,KAAK,WAAW;YACnC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;QAClC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9C,QAAQ,EAAE,UAAU,EAAE,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /** Tailwind's `md` and `sm`. The one place these breakpoints are written outside CSS. */
2
+ export declare const MD_UP = "(min-width: 768px)";
3
+ export declare const SM_UP = "(min-width: 640px)";
4
+ /**
5
+ * A mouse-like primary pointer. Asked this way round, and about `pointer`
6
+ * rather than `any-pointer`, for two reasons:
7
+ *
8
+ * - the fallback below answers `true` to everything, so the query has to be
9
+ * the one whose `true` is the desktop branch;
10
+ * - `any-pointer: coarse` flips a touchscreen laptop, whose primary pointer
11
+ * is a mouse, onto the touch branch for good.
12
+ */
13
+ export declare const POINTER_FINE = "(pointer: fine)";
14
+ /**
15
+ * Whether `query` matches, re-rendering when the answer changes.
16
+ *
17
+ * The snapshot is read during render rather than from an effect, so the
18
+ * first frame already branches the right way. An effect would paint one
19
+ * branch and correct it a frame later, which reads as a flash.
20
+ */
21
+ export declare function useMediaQuery(query: string): boolean;
22
+ //# sourceMappingURL=use-media-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-query.d.ts","sourceRoot":"","sources":["../../src/hooks/use-media-query.ts"],"names":[],"mappings":"AAEA,yFAAyF;AACzF,eAAO,MAAM,KAAK,uBAAuB,CAAC;AAC1C,eAAO,MAAM,KAAK,uBAAuB,CAAC;AAE1C;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,oBAAoB,CAAC;AAQ9C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAWpD"}
@@ -0,0 +1,38 @@
1
+ import { useCallback, useSyncExternalStore } from "react";
2
+ /** Tailwind's `md` and `sm`. The one place these breakpoints are written outside CSS. */
3
+ export const MD_UP = "(min-width: 768px)";
4
+ export const SM_UP = "(min-width: 640px)";
5
+ /**
6
+ * A mouse-like primary pointer. Asked this way round, and about `pointer`
7
+ * rather than `any-pointer`, for two reasons:
8
+ *
9
+ * - the fallback below answers `true` to everything, so the query has to be
10
+ * the one whose `true` is the desktop branch;
11
+ * - `any-pointer: coarse` flips a touchscreen laptop, whose primary pointer
12
+ * is a mouse, onto the touch branch for good.
13
+ */
14
+ export const POINTER_FINE = "(pointer: fine)";
15
+ /** Engines without `matchMedia` get the wide branch, the desktop one. */
16
+ function evaluate(query) {
17
+ if (typeof window.matchMedia !== "function")
18
+ return true;
19
+ return window.matchMedia(query).matches;
20
+ }
21
+ /**
22
+ * Whether `query` matches, re-rendering when the answer changes.
23
+ *
24
+ * The snapshot is read during render rather than from an effect, so the
25
+ * first frame already branches the right way. An effect would paint one
26
+ * branch and correct it a frame later, which reads as a flash.
27
+ */
28
+ export function useMediaQuery(query) {
29
+ const subscribe = useCallback((onStoreChange) => {
30
+ if (typeof window.matchMedia !== "function")
31
+ return () => { };
32
+ const list = window.matchMedia(query);
33
+ list.addEventListener("change", onStoreChange);
34
+ return () => list.removeEventListener("change", onStoreChange);
35
+ }, [query]);
36
+ return useSyncExternalStore(subscribe, () => evaluate(query));
37
+ }
38
+ //# sourceMappingURL=use-media-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-query.js","sourceRoot":"","sources":["../../src/hooks/use-media-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE1D,yFAAyF;AACzF,MAAM,CAAC,MAAM,KAAK,GAAG,oBAAoB,CAAC;AAC1C,MAAM,CAAC,MAAM,KAAK,GAAG,oBAAoB,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,iBAAiB,CAAC;AAE9C,yEAAyE;AACzE,SAAS,QAAQ,CAAC,KAAa;IAC7B,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,aAAyB,EAAE,EAAE;QAC5B,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC/C,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjE,CAAC,EACD,CAAC,KAAK,CAAC,CACR,CAAC;IACF,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { type PartialOptions } from "overlayscrollbars";
2
+ /**
3
+ * Overlay scrollbars for a scroll container that stays exactly as it is: the
4
+ * element `viewport` is on keeps its own classes, its own children and its own
5
+ * native scrolling, and the bars are drawn in `slot`, a positioned parent
6
+ * wrapped directly around it. Needs the `overlayscrollbars` peer, and the
7
+ * consumer imports `overlayscrollbars/overlayscrollbars.css` itself.
8
+ *
9
+ * Both refs are needed. Letting the library build its own viewport moves the
10
+ * children into an inserted div, where the container's `flex gap` no longer
11
+ * reaches them; leaving out the slot leaves the bars inside the scroll
12
+ * container, where they scroll away with the content. A slot further out than
13
+ * the immediate parent draws the bar over whatever else it spans.
14
+ *
15
+ * `ready` withholds the instance until the caller's content is in the DOM.
16
+ * `autoHideSuspend` shows the bar once on arrival — but it only arms when the
17
+ * element already overflows at the moment the instance is created, and a
18
+ * container whose content is still in flight does not. Initializing on mount
19
+ * costs that one reveal outright. Until then the element scrolls natively.
20
+ *
21
+ * `options` go over the defaults above. A container that must never scroll
22
+ * sideways passes `{ overflow: { x: "hidden" } }`: Tailwind's
23
+ * `overflow-y-auto` leaves x computing to `auto`. Pass a stable object — a new
24
+ * identity is applied with `instance.options()`, which costs an update, though
25
+ * never a re-initialization.
26
+ */
27
+ export declare function useOverlayScrollbars(ready: boolean, options?: PartialOptions): {
28
+ slot: import("react").RefObject<HTMLDivElement | null>;
29
+ viewport: import("react").RefObject<HTMLDivElement | null>;
30
+ };
31
+ //# sourceMappingURL=use-overlay-scrollbars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-overlay-scrollbars.d.ts","sourceRoot":"","sources":["../../src/hooks/use-overlay-scrollbars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAqB3E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc;;;EAuC5E"}
@@ -0,0 +1,80 @@
1
+ import { OverlayScrollbars } from "overlayscrollbars";
2
+ import { useEffect, useRef } from "react";
3
+ const DEFAULTS = {
4
+ theme: "os-theme-orz",
5
+ autoHide: "leave",
6
+ autoHideSuspend: true,
7
+ // `false`, the library's default, makes a track click do nothing at all —
8
+ // less than the native behaviour it replaces. Paging instead of jumping
9
+ // would cost a `ClickScrollPlugin` registration.
10
+ clickScroll: "instant",
11
+ };
12
+ /** One level deep, so a caller's `scrollbars` adds to the defaults rather than replacing them. */
13
+ function merged(options) {
14
+ return {
15
+ ...options,
16
+ scrollbars: { ...DEFAULTS, ...options?.scrollbars },
17
+ };
18
+ }
19
+ /**
20
+ * Overlay scrollbars for a scroll container that stays exactly as it is: the
21
+ * element `viewport` is on keeps its own classes, its own children and its own
22
+ * native scrolling, and the bars are drawn in `slot`, a positioned parent
23
+ * wrapped directly around it. Needs the `overlayscrollbars` peer, and the
24
+ * consumer imports `overlayscrollbars/overlayscrollbars.css` itself.
25
+ *
26
+ * Both refs are needed. Letting the library build its own viewport moves the
27
+ * children into an inserted div, where the container's `flex gap` no longer
28
+ * reaches them; leaving out the slot leaves the bars inside the scroll
29
+ * container, where they scroll away with the content. A slot further out than
30
+ * the immediate parent draws the bar over whatever else it spans.
31
+ *
32
+ * `ready` withholds the instance until the caller's content is in the DOM.
33
+ * `autoHideSuspend` shows the bar once on arrival — but it only arms when the
34
+ * element already overflows at the moment the instance is created, and a
35
+ * container whose content is still in flight does not. Initializing on mount
36
+ * costs that one reveal outright. Until then the element scrolls natively.
37
+ *
38
+ * `options` go over the defaults above. A container that must never scroll
39
+ * sideways passes `{ overflow: { x: "hidden" } }`: Tailwind's
40
+ * `overflow-y-auto` leaves x computing to `auto`. Pass a stable object — a new
41
+ * identity is applied with `instance.options()`, which costs an update, though
42
+ * never a re-initialization.
43
+ */
44
+ export function useOverlayScrollbars(ready, options) {
45
+ const slot = useRef(null);
46
+ const viewport = useRef(null);
47
+ const instance = useRef(null);
48
+ const latest = useRef(options);
49
+ latest.current = options;
50
+ // What the live instance was last given, so the mount does not apply the
51
+ // options it was just created with a second time.
52
+ const applied = useRef(undefined);
53
+ useEffect(() => {
54
+ const slotElement = slot.current;
55
+ const viewportElement = viewport.current;
56
+ if (!ready || slotElement === null || viewportElement === null)
57
+ return;
58
+ const created = OverlayScrollbars({
59
+ target: viewportElement,
60
+ elements: { viewport: viewportElement },
61
+ scrollbars: { slot: slotElement },
62
+ }, merged(latest.current));
63
+ instance.current = created;
64
+ applied.current = latest.current;
65
+ return () => {
66
+ instance.current = null;
67
+ created.destroy();
68
+ };
69
+ }, [ready]);
70
+ useEffect(() => {
71
+ if (instance.current === null || applied.current === options)
72
+ return;
73
+ applied.current = options;
74
+ // Pure, so a key the caller stopped passing falls back to its default
75
+ // instead of keeping the value it was last given.
76
+ instance.current.options(merged(options), true);
77
+ }, [options]);
78
+ return { slot, viewport };
79
+ }
80
+ //# sourceMappingURL=use-overlay-scrollbars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-overlay-scrollbars.js","sourceRoot":"","sources":["../../src/hooks/use-overlay-scrollbars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAuB,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,QAAQ,GAAG;IACf,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,OAAO;IACjB,eAAe,EAAE,IAAI;IACrB,0EAA0E;IAC1E,wEAAwE;IACxE,iDAAiD;IACjD,WAAW,EAAE,SAAS;CACyB,CAAC;AAElD,kGAAkG;AAClG,SAAS,MAAM,CAAC,OAAmC;IACjD,OAAO;QACL,GAAG,OAAO;QACV,UAAU,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE;KACpD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc,EAAE,OAAwB;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,yEAAyE;IACzE,kDAAkD;IAClD,MAAM,OAAO,GAAG,MAAM,CAA6B,SAAS,CAAC,CAAC;IAE9D,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;QACjC,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC;QACzC,IAAI,CAAC,KAAK,IAAI,WAAW,KAAK,IAAI,IAAI,eAAe,KAAK,IAAI;YAAE,OAAO;QACvE,MAAM,OAAO,GAAG,iBAAiB,CAC/B;YACE,MAAM,EAAE,eAAe;YACvB,QAAQ,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE;YACvC,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;SAClC,EACD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CACvB,CAAC;QACF,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;QAC3B,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACjC,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;YACxB,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO;YAAE,OAAO;QACrE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;QAC1B,sEAAsE;QACtE,kDAAkD;QAClD,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function usePagedAppend<P>(resetKey: string): {
2
+ pages: P[];
3
+ pending: boolean;
4
+ error: Error | null;
5
+ append: (load: () => Promise<P>) => void;
6
+ };
7
+ //# sourceMappingURL=use-paged-append.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-paged-append.d.ts","sourceRoot":"","sources":["../../src/hooks/use-paged-append.ts"],"names":[],"mappings":"AAcA,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG;IACnD,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAC1C,CA0DA"}