@moldable-ai/ui 0.2.20 → 0.2.22

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 (196) hide show
  1. package/dist/catalog/catalog-coverage.d.ts +15 -0
  2. package/dist/catalog/catalog-coverage.d.ts.map +1 -0
  3. package/dist/catalog/catalog-coverage.js +44 -0
  4. package/dist/catalog/catalog-manifest.d.ts.map +1 -1
  5. package/dist/catalog/catalog-manifest.js +35 -23
  6. package/dist/catalog/catalog-types.d.ts +17 -0
  7. package/dist/catalog/catalog-types.d.ts.map +1 -1
  8. package/dist/catalog/catalog-types.js +7 -0
  9. package/dist/catalog/component-catalog.d.ts.map +1 -1
  10. package/dist/catalog/component-catalog.js +16 -6
  11. package/dist/catalog/core-catalog-exclusions.d.ts +8 -0
  12. package/dist/catalog/core-catalog-exclusions.d.ts.map +1 -0
  13. package/dist/catalog/core-catalog-exclusions.js +155 -0
  14. package/dist/catalog/core-catalog.d.ts +0 -4
  15. package/dist/catalog/core-catalog.d.ts.map +1 -1
  16. package/dist/catalog/core-catalog.js +12 -98
  17. package/dist/catalog/core-collection-stories.d.ts +3 -0
  18. package/dist/catalog/core-collection-stories.d.ts.map +1 -0
  19. package/dist/catalog/core-collection-stories.js +42 -0
  20. package/dist/catalog/core-control-stories.d.ts +3 -0
  21. package/dist/catalog/core-control-stories.d.ts.map +1 -0
  22. package/dist/catalog/core-control-stories.js +97 -0
  23. package/dist/catalog/core-feedback-stories.d.ts +3 -0
  24. package/dist/catalog/core-feedback-stories.d.ts.map +1 -0
  25. package/dist/catalog/core-feedback-stories.js +50 -0
  26. package/dist/catalog/core-foundation-stories.d.ts +3 -0
  27. package/dist/catalog/core-foundation-stories.d.ts.map +1 -0
  28. package/dist/catalog/core-foundation-stories.js +53 -0
  29. package/dist/catalog/core-navigation-stories.d.ts +3 -0
  30. package/dist/catalog/core-navigation-stories.d.ts.map +1 -0
  31. package/dist/catalog/core-navigation-stories.js +25 -0
  32. package/dist/catalog/core-overlay-stories.d.ts +3 -0
  33. package/dist/catalog/core-overlay-stories.d.ts.map +1 -0
  34. package/dist/catalog/core-overlay-stories.js +20 -0
  35. package/dist/catalog/index.d.ts +3 -1
  36. package/dist/catalog/index.d.ts.map +1 -1
  37. package/dist/catalog/index.js +3 -1
  38. package/dist/components/app-error-boundary.d.ts.map +1 -1
  39. package/dist/components/app-error-boundary.js +3 -2
  40. package/dist/components/chat/chat-panel.d.ts +0 -1
  41. package/dist/components/chat/chat-panel.d.ts.map +1 -1
  42. package/dist/components/chat/chat-panel.js +7 -11
  43. package/dist/components/ui/alert-dialog.d.ts +10 -4
  44. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  45. package/dist/components/ui/alert-dialog.js +14 -6
  46. package/dist/components/ui/alert.d.ts +19 -3
  47. package/dist/components/ui/alert.d.ts.map +1 -1
  48. package/dist/components/ui/alert.js +25 -8
  49. package/dist/components/ui/app-frame.d.ts +9 -3
  50. package/dist/components/ui/app-frame.d.ts.map +1 -1
  51. package/dist/components/ui/app-frame.js +45 -6
  52. package/dist/components/ui/button.d.ts +6 -4
  53. package/dist/components/ui/button.d.ts.map +1 -1
  54. package/dist/components/ui/button.js +40 -8
  55. package/dist/components/ui/collapsible.d.ts +9 -1
  56. package/dist/components/ui/collapsible.d.ts.map +1 -1
  57. package/dist/components/ui/collapsible.js +13 -2
  58. package/dist/components/ui/collection-navigation.d.ts +8 -0
  59. package/dist/components/ui/collection-navigation.d.ts.map +1 -0
  60. package/dist/components/ui/collection-navigation.js +19 -0
  61. package/dist/components/ui/command.d.ts +5 -1
  62. package/dist/components/ui/command.d.ts.map +1 -1
  63. package/dist/components/ui/command.js +13 -1
  64. package/dist/components/ui/confirm-dialog.d.ts +19 -0
  65. package/dist/components/ui/confirm-dialog.d.ts.map +1 -0
  66. package/dist/components/ui/confirm-dialog.js +45 -0
  67. package/dist/components/ui/date-picker.d.ts +24 -0
  68. package/dist/components/ui/date-picker.d.ts.map +1 -0
  69. package/dist/components/ui/date-picker.js +92 -0
  70. package/dist/components/ui/dialog-primary-action.d.ts +4 -0
  71. package/dist/components/ui/dialog-primary-action.d.ts.map +1 -0
  72. package/dist/components/ui/dialog-primary-action.js +37 -0
  73. package/dist/components/ui/dialog.d.ts +8 -2
  74. package/dist/components/ui/dialog.d.ts.map +1 -1
  75. package/dist/components/ui/dialog.js +15 -5
  76. package/dist/components/ui/empty.d.ts +7 -2
  77. package/dist/components/ui/empty.d.ts.map +1 -1
  78. package/dist/components/ui/empty.js +20 -7
  79. package/dist/components/ui/error-boundary-view.d.ts +12 -0
  80. package/dist/components/ui/error-boundary-view.d.ts.map +1 -0
  81. package/dist/components/ui/error-boundary-view.js +8 -0
  82. package/dist/components/ui/grid.d.ts.map +1 -1
  83. package/dist/components/ui/grid.js +70 -46
  84. package/dist/components/ui/icon-button.d.ts.map +1 -1
  85. package/dist/components/ui/icon-button.js +1 -2
  86. package/dist/components/ui/index.d.ts +5 -0
  87. package/dist/components/ui/index.d.ts.map +1 -1
  88. package/dist/components/ui/index.js +5 -0
  89. package/dist/components/ui/input-group.d.ts +1 -1
  90. package/dist/components/ui/list.d.ts +5 -1
  91. package/dist/components/ui/list.d.ts.map +1 -1
  92. package/dist/components/ui/list.js +27 -16
  93. package/dist/components/ui/material.d.ts +34 -0
  94. package/dist/components/ui/material.d.ts.map +1 -0
  95. package/dist/components/ui/material.js +34 -0
  96. package/dist/components/ui/message-scroller-controller.d.ts +162 -0
  97. package/dist/components/ui/message-scroller-controller.d.ts.map +1 -0
  98. package/dist/components/ui/message-scroller-controller.js +888 -0
  99. package/dist/components/ui/message-scroller-policy.d.ts +74 -0
  100. package/dist/components/ui/message-scroller-policy.d.ts.map +1 -0
  101. package/dist/components/ui/message-scroller-policy.js +129 -0
  102. package/dist/components/ui/message-scroller-primitive.d.ts +55 -0
  103. package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -0
  104. package/dist/components/ui/message-scroller-primitive.js +226 -0
  105. package/dist/components/ui/message-scroller.d.ts +2 -2
  106. package/dist/components/ui/message-scroller.d.ts.map +1 -1
  107. package/dist/components/ui/message-scroller.js +3 -15
  108. package/dist/components/ui/navigation-button-group.d.ts +16 -0
  109. package/dist/components/ui/navigation-button-group.d.ts.map +1 -0
  110. package/dist/components/ui/navigation-button-group.js +9 -0
  111. package/dist/components/ui/popover.d.ts +9 -2
  112. package/dist/components/ui/popover.d.ts.map +1 -1
  113. package/dist/components/ui/popover.js +13 -3
  114. package/dist/components/ui/scroll-area.d.ts +8 -2
  115. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  116. package/dist/components/ui/scroll-area.js +6 -3
  117. package/dist/components/ui/search-field.d.ts.map +1 -1
  118. package/dist/components/ui/segmented-control.d.ts.map +1 -1
  119. package/dist/components/ui/segmented-control.js +6 -5
  120. package/dist/components/ui/sheet.d.ts +4 -2
  121. package/dist/components/ui/sheet.d.ts.map +1 -1
  122. package/dist/components/ui/sheet.js +12 -9
  123. package/dist/components/ui/sonner.d.ts +1 -1
  124. package/dist/components/ui/sonner.d.ts.map +1 -1
  125. package/dist/components/ui/spinner.d.ts.map +1 -1
  126. package/dist/components/ui/spinner.js +1 -1
  127. package/dist/components/ui/table.d.ts.map +1 -1
  128. package/dist/components/ui/table.js +7 -2
  129. package/dist/components/ui/toggle.d.ts +12 -4
  130. package/dist/components/ui/toggle.d.ts.map +1 -1
  131. package/dist/components/ui/toggle.js +13 -2
  132. package/dist/components/ui/toolbar.d.ts +9 -2
  133. package/dist/components/ui/toolbar.d.ts.map +1 -1
  134. package/dist/components/ui/toolbar.js +23 -4
  135. package/dist/components/ui/tooltip.d.ts +8 -3
  136. package/dist/components/ui/tooltip.d.ts.map +1 -1
  137. package/dist/components/ui/tooltip.js +11 -6
  138. package/dist/index.d.ts +6 -1
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +7 -1
  141. package/dist/lib/frame-lifecycle.d.ts +23 -0
  142. package/dist/lib/frame-lifecycle.d.ts.map +1 -1
  143. package/dist/lib/frame-lifecycle.js +30 -3
  144. package/dist/lib/host-date-time-picker.d.ts +36 -0
  145. package/dist/lib/host-date-time-picker.d.ts.map +1 -0
  146. package/dist/lib/host-date-time-picker.js +162 -0
  147. package/dist/lib/host-file-dialog.d.ts +66 -0
  148. package/dist/lib/host-file-dialog.d.ts.map +1 -0
  149. package/dist/lib/host-file-dialog.js +221 -0
  150. package/dist/lib/host-native-menu.d.ts +75 -0
  151. package/dist/lib/host-native-menu.d.ts.map +1 -0
  152. package/dist/lib/host-native-menu.js +187 -0
  153. package/dist/lib/host-services.d.ts +13 -0
  154. package/dist/lib/host-services.d.ts.map +1 -0
  155. package/dist/lib/host-services.js +161 -0
  156. package/dist/lib/host-share.d.ts +39 -0
  157. package/dist/lib/host-share.d.ts.map +1 -0
  158. package/dist/lib/host-share.js +161 -0
  159. package/dist/lib/theme.d.ts.map +1 -1
  160. package/dist/lib/theme.js +2 -1
  161. package/docs/README.md +4 -1
  162. package/docs/adaptive-materials.md +79 -0
  163. package/docs/app-anatomy.md +3 -1
  164. package/docs/component-catalog.md +26 -3
  165. package/docs/design-tokens.md +17 -4
  166. package/docs/foundations.md +5 -3
  167. package/docs/standalone-app-windows.md +8 -0
  168. package/docs/visual-regression.md +78 -0
  169. package/package.json +12 -4
  170. package/src/components/ui/alert-dialog.md +58 -0
  171. package/src/components/ui/alert.md +28 -6
  172. package/src/components/ui/app-frame.md +5 -0
  173. package/src/components/ui/button.md +10 -3
  174. package/src/components/ui/collapsible.md +52 -0
  175. package/src/components/ui/combobox.md +0 -1
  176. package/src/components/ui/command.md +54 -0
  177. package/src/components/ui/date-field.md +1 -1
  178. package/src/components/ui/date-picker.md +55 -0
  179. package/src/components/ui/dialog.md +59 -0
  180. package/src/components/ui/empty.md +8 -3
  181. package/src/components/ui/error-boundary-view.md +98 -0
  182. package/src/components/ui/grid.md +8 -4
  183. package/src/components/ui/icon-button.md +2 -2
  184. package/src/components/ui/list.md +35 -2
  185. package/src/components/ui/material.md +51 -0
  186. package/src/components/ui/navigation-button-group.md +46 -0
  187. package/src/components/ui/popover.md +31 -0
  188. package/src/components/ui/scroll-area.md +11 -7
  189. package/src/components/ui/search-field.md +1 -1
  190. package/src/components/ui/segmented-control.md +2 -5
  191. package/src/components/ui/sheet.md +30 -0
  192. package/src/components/ui/table.md +4 -2
  193. package/src/components/ui/toggle-button.md +48 -0
  194. package/src/components/ui/toolbar.md +5 -0
  195. package/src/components/ui/tooltip.md +31 -0
  196. package/src/styles/index.css +213 -0
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Pure scroll-ownership policy for the chat transcript.
3
+ *
4
+ * One rule outranks everything: the reader's scroll intent wins instantly.
5
+ * Programmatic motion is explicit — every scroll the primitive itself starts
6
+ * declares a target — so any viewport movement that was not commanded is, by
7
+ * definition, the user. That includes native scrollbar drags, which emit no
8
+ * wheel, pointer, or key events at all.
9
+ *
10
+ * The previous stack (upstream shadcn primitive + a local layout-stability
11
+ * patch) ran two competing controllers with grace timers and an
12
+ * "autoscrolling" veto window; a scrollbar drag during streaming could not
13
+ * release follow mode, so the next content growth yanked the viewport back
14
+ * down. This module replaces both with a single mode machine, mirroring the
15
+ * MessageScrollerPolicy used by the iOS transcript.
16
+ */
17
+ export type MessageScrollerMode =
18
+ /** Pinned to the newest output; content growth keeps the end in view. */
19
+ 'following-end'
20
+ /** The reader owns the position; the scroller never moves it. */
21
+ | 'free'
22
+ /** A turn anchor is pinned near the viewport top while output streams. */
23
+ | 'anchored'
24
+ /** A commanded jump is in flight; resolves on arrival or user motion. */
25
+ | 'settling-jump';
26
+ export type MessageScrollerResizeAction = 'stick-to-end' | 'reanchor' | 'preserve-reading-position' | 'none';
27
+ export interface MessageScrollerScrollEvent {
28
+ scrollTop: number;
29
+ lastScrollTop: number;
30
+ atEnd: boolean;
31
+ }
32
+ export declare class MessageScrollerPolicy {
33
+ mode: MessageScrollerMode;
34
+ autoScroll: boolean;
35
+ /**
36
+ * The destination of the programmatic scroll currently in flight, if any.
37
+ * Smooth scrolls pass through many intermediate positions; they count as
38
+ * our own motion only while they keep approaching this target.
39
+ */
40
+ programmaticTarget: number | null;
41
+ private lastDistanceToTarget;
42
+ constructor(autoScroll: boolean);
43
+ get followsEnd(): boolean;
44
+ /** Declares a programmatic scroll about to start toward `target`. */
45
+ beginProgrammaticScroll(target: number): void;
46
+ /**
47
+ * Abandons an in-flight programmatic scroll that will never arrive (the
48
+ * animation was dropped or its target became unreachable). Subsequent
49
+ * movement is classified as the reader's.
50
+ */
51
+ cancelProgrammaticScroll(): void;
52
+ /**
53
+ * Classifies a scroll event and returns true when it was the reader's own
54
+ * motion. Programmatic motion is recognized by monotonic approach to the
55
+ * declared target; everything else — wheel, trackpad, keyboard, scrollbar
56
+ * drag, momentum — is user motion and takes ownership immediately.
57
+ */
58
+ handleScrollEvent(event: MessageScrollerScrollEvent): boolean;
59
+ /**
60
+ * Explicit input intent (wheel, touch, scroll keys). Upward intent releases
61
+ * immediately — before the scroll event lands — so a resize racing the
62
+ * same frame cannot pull the viewport down first.
63
+ */
64
+ handleUserIntent(direction: 'up' | 'down' | 'unknown'): void;
65
+ /** How a content size change may move the viewport in the current mode. */
66
+ resizeAction(): MessageScrollerResizeAction;
67
+ /** A new turn anchor was appended and commanded into view. */
68
+ anchorToTurn(): void;
69
+ beginJump(): void;
70
+ jumpToEnd(): void;
71
+ jumpToStart(): void;
72
+ release(): void;
73
+ }
74
+ //# sourceMappingURL=message-scroller-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-scroller-policy.d.ts","sourceRoot":"","sources":["../../../src/components/ui/message-scroller-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,mBAAmB;AAC7B,yEAAyE;AACvE,eAAe;AACjB,iEAAiE;GAC/D,MAAM;AACR,0EAA0E;GACxE,UAAU;AACZ,yEAAyE;GACvE,eAAe,CAAA;AAEnB,MAAM,MAAM,2BAA2B,GACnC,cAAc,GACd,UAAU,GACV,2BAA2B,GAC3B,MAAM,CAAA;AAKV,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,OAAO,CAAA;CACf;AAED,qBAAa,qBAAqB;IAChC,IAAI,EAAE,mBAAmB,CAAA;IACzB,UAAU,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAO;IACxC,OAAO,CAAC,oBAAoB,CAA2B;gBAE3C,UAAU,EAAE,OAAO;IAK/B,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,qEAAqE;IACrE,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK7C;;;;OAIG;IACH,wBAAwB,IAAI,IAAI;IAOhC;;;;;OAKG;IACH,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO;IA6B7D;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI;IAK5D,2EAA2E;IAC3E,YAAY,IAAI,2BAA2B;IAgB3C,8DAA8D;IAC9D,YAAY,IAAI,IAAI;IAIpB,SAAS,IAAI,IAAI;IAIjB,SAAS,IAAI,IAAI;IAIjB,WAAW,IAAI,IAAI;IAInB,OAAO,IAAI,IAAI;CAGhB"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Pure scroll-ownership policy for the chat transcript.
3
+ *
4
+ * One rule outranks everything: the reader's scroll intent wins instantly.
5
+ * Programmatic motion is explicit — every scroll the primitive itself starts
6
+ * declares a target — so any viewport movement that was not commanded is, by
7
+ * definition, the user. That includes native scrollbar drags, which emit no
8
+ * wheel, pointer, or key events at all.
9
+ *
10
+ * The previous stack (upstream shadcn primitive + a local layout-stability
11
+ * patch) ran two competing controllers with grace timers and an
12
+ * "autoscrolling" veto window; a scrollbar drag during streaming could not
13
+ * release follow mode, so the next content growth yanked the viewport back
14
+ * down. This module replaces both with a single mode machine, mirroring the
15
+ * MessageScrollerPolicy used by the iOS transcript.
16
+ */
17
+ const SCROLL_EPSILON_PX = 0.5;
18
+ const TARGET_ARRIVAL_PX = 1;
19
+ export class MessageScrollerPolicy {
20
+ mode;
21
+ autoScroll;
22
+ /**
23
+ * The destination of the programmatic scroll currently in flight, if any.
24
+ * Smooth scrolls pass through many intermediate positions; they count as
25
+ * our own motion only while they keep approaching this target.
26
+ */
27
+ programmaticTarget = null;
28
+ lastDistanceToTarget = Number.POSITIVE_INFINITY;
29
+ constructor(autoScroll) {
30
+ this.autoScroll = autoScroll;
31
+ this.mode = autoScroll ? 'following-end' : 'free';
32
+ }
33
+ get followsEnd() {
34
+ return this.mode === 'following-end';
35
+ }
36
+ /** Declares a programmatic scroll about to start toward `target`. */
37
+ beginProgrammaticScroll(target) {
38
+ this.programmaticTarget = target;
39
+ this.lastDistanceToTarget = Number.POSITIVE_INFINITY;
40
+ }
41
+ /**
42
+ * Abandons an in-flight programmatic scroll that will never arrive (the
43
+ * animation was dropped or its target became unreachable). Subsequent
44
+ * movement is classified as the reader's.
45
+ */
46
+ cancelProgrammaticScroll() {
47
+ if (this.programmaticTarget === null)
48
+ return;
49
+ this.programmaticTarget = null;
50
+ this.lastDistanceToTarget = Number.POSITIVE_INFINITY;
51
+ if (this.mode === 'settling-jump')
52
+ this.mode = 'free';
53
+ }
54
+ /**
55
+ * Classifies a scroll event and returns true when it was the reader's own
56
+ * motion. Programmatic motion is recognized by monotonic approach to the
57
+ * declared target; everything else — wheel, trackpad, keyboard, scrollbar
58
+ * drag, momentum — is user motion and takes ownership immediately.
59
+ */
60
+ handleScrollEvent(event) {
61
+ if (this.programmaticTarget !== null) {
62
+ const distance = Math.abs(event.scrollTop - this.programmaticTarget);
63
+ if (distance <= TARGET_ARRIVAL_PX) {
64
+ this.programmaticTarget = null;
65
+ this.lastDistanceToTarget = Number.POSITIVE_INFINITY;
66
+ if (this.mode === 'settling-jump') {
67
+ this.mode = event.atEnd && this.autoScroll ? 'following-end' : 'free';
68
+ }
69
+ return false;
70
+ }
71
+ if (distance <= this.lastDistanceToTarget + SCROLL_EPSILON_PX) {
72
+ this.lastDistanceToTarget = distance;
73
+ return false;
74
+ }
75
+ // Motion away from our own target: the reader grabbed the viewport
76
+ // mid-flight. The jump loses.
77
+ this.programmaticTarget = null;
78
+ this.lastDistanceToTarget = Number.POSITIVE_INFINITY;
79
+ }
80
+ const movedUp = event.scrollTop < event.lastScrollTop - SCROLL_EPSILON_PX;
81
+ const movedDown = event.scrollTop > event.lastScrollTop + SCROLL_EPSILON_PX;
82
+ if (!movedUp && !movedDown)
83
+ return false;
84
+ this.mode = event.atEnd && this.autoScroll ? 'following-end' : 'free';
85
+ return true;
86
+ }
87
+ /**
88
+ * Explicit input intent (wheel, touch, scroll keys). Upward intent releases
89
+ * immediately — before the scroll event lands — so a resize racing the
90
+ * same frame cannot pull the viewport down first.
91
+ */
92
+ handleUserIntent(direction) {
93
+ if (this.mode === 'following-end' && direction === 'down')
94
+ return;
95
+ this.mode = 'free';
96
+ }
97
+ /** How a content size change may move the viewport in the current mode. */
98
+ resizeAction() {
99
+ switch (this.mode) {
100
+ case 'following-end':
101
+ return 'stick-to-end';
102
+ case 'anchored':
103
+ return 'reanchor';
104
+ case 'settling-jump':
105
+ return 'none';
106
+ case 'free':
107
+ // A collapsing disclosure above the reader must not shift what they
108
+ // are looking at. Native scroll anchoring usually handles it; the
109
+ // caller re-pins the first visible stable leaf when it does not.
110
+ return 'preserve-reading-position';
111
+ }
112
+ }
113
+ /** A new turn anchor was appended and commanded into view. */
114
+ anchorToTurn() {
115
+ this.mode = 'anchored';
116
+ }
117
+ beginJump() {
118
+ this.mode = 'settling-jump';
119
+ }
120
+ jumpToEnd() {
121
+ this.mode = this.autoScroll ? 'following-end' : 'free';
122
+ }
123
+ jumpToStart() {
124
+ this.mode = 'free';
125
+ }
126
+ release() {
127
+ this.mode = 'free';
128
+ }
129
+ }
@@ -0,0 +1,55 @@
1
+ import * as React from 'react';
2
+ import { type MessageScrollerDefaultScrollPosition, type MessageScrollerScrollAlign, type MessageScrollerScrollOptions, type MessageScrollerScrollable, type MessageScrollerVisibilityState } from './message-scroller-controller';
3
+ type MessageScrollerProviderProps = {
4
+ children?: React.ReactNode;
5
+ autoScroll?: boolean;
6
+ defaultScrollPosition?: MessageScrollerDefaultScrollPosition;
7
+ scrollEdgeThreshold?: number;
8
+ scrollPreviousItemPeek?: number;
9
+ scrollMargin?: number;
10
+ };
11
+ declare function MessageScrollerProvider({ autoScroll, children, defaultScrollPosition, scrollEdgeThreshold, scrollPreviousItemPeek, scrollMargin, }: MessageScrollerProviderProps): import("react/jsx-runtime").JSX.Element;
12
+ type MessageScrollerProps = React.ComponentProps<'div'>;
13
+ declare function MessageScrollerRoot({ children, ...props }: MessageScrollerProps): import("react/jsx-runtime").JSX.Element;
14
+ type MessageScrollerViewportProps = React.ComponentProps<'div'> & {
15
+ preserveScrollOnPrepend?: boolean;
16
+ };
17
+ declare function MessageScrollerViewport({ 'aria-label': ariaLabel, children, onKeyDown, onScroll, onTouchMove, onWheel, preserveScrollOnPrepend, ref, role, tabIndex, ...props }: MessageScrollerViewportProps): import("react/jsx-runtime").JSX.Element;
18
+ type MessageScrollerContentProps = React.ComponentProps<'div'> & {
19
+ spacerClassName?: string;
20
+ };
21
+ declare function MessageScrollerContent({ 'aria-relevant': ariaRelevant, children, ref, role, spacerClassName, ...props }: MessageScrollerContentProps): import("react/jsx-runtime").JSX.Element;
22
+ type MessageScrollerItemProps = React.ComponentProps<'div'> & {
23
+ messageId?: string;
24
+ scrollAnchor?: boolean;
25
+ };
26
+ declare function MessageScrollerItem({ messageId, ref, scrollAnchor, ...props }: MessageScrollerItemProps): import("react/jsx-runtime").JSX.Element;
27
+ type MessageScrollerButtonDirection = 'start' | 'end';
28
+ type MessageScrollerButtonRenderState = {
29
+ active: boolean;
30
+ direction: MessageScrollerButtonDirection;
31
+ };
32
+ type MessageScrollerButtonProps = Omit<React.ComponentProps<'button'>, 'children'> & {
33
+ behavior?: ScrollBehavior;
34
+ children?: React.ReactNode;
35
+ direction?: MessageScrollerButtonDirection;
36
+ render?: React.ReactElement<Record<string, unknown>> | ((props: Record<string, unknown>, state: MessageScrollerButtonRenderState) => React.ReactElement | null);
37
+ };
38
+ declare function MessageScrollerButton({ behavior, children, className, direction, onClick, render, tabIndex, type, ...props }: MessageScrollerButtonProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | null;
39
+ declare function useMessageScroller(): {
40
+ scrollToEnd: (options?: MessageScrollerScrollOptions) => boolean;
41
+ scrollToMessage: (messageId: string, options?: MessageScrollerScrollOptions) => boolean;
42
+ scrollToStart: (options?: MessageScrollerScrollOptions) => boolean;
43
+ };
44
+ declare function useMessageScrollerScrollable(): MessageScrollerScrollable;
45
+ declare function useMessageScrollerVisibility(): MessageScrollerVisibilityState;
46
+ declare const MessageScroller: {
47
+ Provider: typeof MessageScrollerProvider;
48
+ Root: typeof MessageScrollerRoot;
49
+ Viewport: typeof MessageScrollerViewport;
50
+ Content: typeof MessageScrollerContent;
51
+ Item: typeof MessageScrollerItem;
52
+ Button: typeof MessageScrollerButton;
53
+ };
54
+ export { MessageScroller, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, type MessageScrollerDefaultScrollPosition, type MessageScrollerScrollAlign, type MessageScrollerScrollOptions, type MessageScrollerScrollable, type MessageScrollerVisibilityState, };
55
+ //# sourceMappingURL=message-scroller-primitive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-scroller-primitive.d.ts","sourceRoot":"","sources":["../../../src/components/ui/message-scroller-primitive.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,226 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { MessageScrollerController, } from './message-scroller-controller';
5
+ /**
6
+ * The transcript scroller primitive, owned in-repo. Drop-in compatible with
7
+ * the `@shadcn/react/message-scroller` surface it replaces, but built around
8
+ * a single scroll-ownership policy (`message-scroller-policy.ts`) shared in
9
+ * design with the iOS transcript. See that module for the rules; the React
10
+ * layer here only wires DOM events and observers to the controller.
11
+ */
12
+ const SCROLL_KEYS = new Set([
13
+ 'ArrowDown',
14
+ 'ArrowUp',
15
+ 'End',
16
+ 'Home',
17
+ 'PageDown',
18
+ 'PageUp',
19
+ ' ',
20
+ ]);
21
+ const ControllerContext = React.createContext(null);
22
+ const RegisterMessageContext = React.createContext(null);
23
+ function useController() {
24
+ const controller = React.useContext(ControllerContext);
25
+ if (!controller) {
26
+ throw new Error('useMessageScroller must be used within a MessageScroller.');
27
+ }
28
+ return controller;
29
+ }
30
+ function MessageScrollerProvider({ autoScroll = false, children, defaultScrollPosition = 'end', scrollEdgeThreshold = 8, scrollPreviousItemPeek = 64, scrollMargin = 0, }) {
31
+ const options = {
32
+ autoScroll,
33
+ defaultScrollPosition,
34
+ scrollEdgeThreshold,
35
+ scrollPreviousItemPeek,
36
+ scrollMargin,
37
+ };
38
+ const controllerRef = React.useRef(null);
39
+ controllerRef.current ??= new MessageScrollerController(options);
40
+ const controller = controllerRef.current;
41
+ const previousDefaultPosition = React.useRef(defaultScrollPosition);
42
+ if (previousDefaultPosition.current !== defaultScrollPosition) {
43
+ previousDefaultPosition.current = defaultScrollPosition;
44
+ controller.resetDefaultPosition();
45
+ }
46
+ controller.updateOptions(options);
47
+ React.useEffect(() => () => controller.destroy(), [controller]);
48
+ const registerMessage = React.useCallback((messageId, element, previous) => controller.registerMessage(messageId, element, previous), [controller]);
49
+ return (_jsx(ControllerContext.Provider, { value: controller, children: _jsx(RegisterMessageContext.Provider, { value: registerMessage, children: children }) }));
50
+ }
51
+ function MessageScrollerRoot({ children, ...props }) {
52
+ const controller = useController();
53
+ const setRoot = React.useCallback((element) => controller.setRoot(element), [controller]);
54
+ return (_jsx("div", { ref: setRoot, ...props, children: children }));
55
+ }
56
+ function MessageScrollerViewport({ 'aria-label': ariaLabel, children, onKeyDown, onScroll, onTouchMove, onWheel, preserveScrollOnPrepend = true, ref, role, tabIndex, ...props }) {
57
+ const controller = useController();
58
+ controller.preserveScrollOnPrepend = preserveScrollOnPrepend;
59
+ const setViewport = React.useCallback((element) => {
60
+ controller.setViewport(element);
61
+ if (typeof ref === 'function')
62
+ ref(element);
63
+ else if (ref)
64
+ ref.current = element;
65
+ }, [controller, ref]);
66
+ React.useEffect(() => {
67
+ const viewport = controller.viewportElement;
68
+ if (!viewport || typeof ResizeObserver === 'undefined')
69
+ return;
70
+ let frame = 0;
71
+ const observer = new ResizeObserver(() => {
72
+ cancelAnimationFrame(frame);
73
+ frame = requestAnimationFrame(() => controller.handleResize());
74
+ });
75
+ observer.observe(viewport);
76
+ return () => {
77
+ cancelAnimationFrame(frame);
78
+ observer.disconnect();
79
+ };
80
+ }, [controller]);
81
+ return (_jsx("div", { ref: setViewport, role: role ?? 'region', "aria-label": ariaLabel ?? 'Messages', tabIndex: tabIndex ?? 0, onScroll: (event) => {
82
+ controller.handleScroll();
83
+ onScroll?.(event);
84
+ }, onWheel: (event) => {
85
+ controller.handleWheel(event.deltaY);
86
+ onWheel?.(event);
87
+ }, onTouchMove: (event) => {
88
+ controller.handleTouchMove();
89
+ onTouchMove?.(event);
90
+ }, onKeyDown: (event) => {
91
+ if (SCROLL_KEYS.has(event.key))
92
+ controller.handleScrollKey();
93
+ onKeyDown?.(event);
94
+ }, ...props, children: children }));
95
+ }
96
+ function MessageScrollerContent({ 'aria-relevant': ariaRelevant, children, ref, role, spacerClassName, ...props }) {
97
+ const controller = useController();
98
+ const contentRef = React.useRef(null);
99
+ const setContent = React.useCallback((element) => {
100
+ contentRef.current = element;
101
+ controller.setContent(element);
102
+ if (typeof ref === 'function')
103
+ ref(element);
104
+ else if (ref)
105
+ ref.current = element;
106
+ }, [controller, ref]);
107
+ const setSpacer = React.useCallback((element) => controller.setSpacer(element), [controller]);
108
+ React.useLayoutEffect(() => {
109
+ const content = contentRef.current;
110
+ if (!content)
111
+ return;
112
+ controller.handleContentMutation();
113
+ if (typeof MutationObserver === 'undefined')
114
+ return;
115
+ const observer = new MutationObserver(() => controller.handleContentMutation());
116
+ observer.observe(content, { childList: true });
117
+ return () => observer.disconnect();
118
+ }, [controller]);
119
+ React.useEffect(() => {
120
+ const content = contentRef.current;
121
+ if (!content || typeof ResizeObserver === 'undefined')
122
+ return;
123
+ let frame = 0;
124
+ const observer = new ResizeObserver(() => {
125
+ cancelAnimationFrame(frame);
126
+ frame = requestAnimationFrame(() => controller.handleResize());
127
+ });
128
+ observer.observe(content);
129
+ return () => {
130
+ cancelAnimationFrame(frame);
131
+ observer.disconnect();
132
+ };
133
+ }, [controller]);
134
+ return (_jsxs("div", { ref: setContent, role: role ?? 'log', "aria-relevant": ariaRelevant ?? 'additions', ...props, children: [children, _jsx("div", { ref: setSpacer, "aria-hidden": "true", "data-message-scroller-spacer": "", hidden: true, className: spacerClassName })] }));
135
+ }
136
+ function MessageScrollerItem({ messageId, ref, scrollAnchor = false, ...props }) {
137
+ const registerMessage = React.useContext(RegisterMessageContext);
138
+ if (!registerMessage) {
139
+ throw new Error('MessageScrollerItem must be used within a MessageScroller.');
140
+ }
141
+ const elementRef = React.useRef(null);
142
+ const setElement = React.useCallback((element) => {
143
+ const previous = elementRef.current;
144
+ elementRef.current = element;
145
+ if (messageId)
146
+ registerMessage(messageId, element, previous);
147
+ if (typeof ref === 'function')
148
+ ref(element);
149
+ else if (ref)
150
+ ref.current = element;
151
+ }, [messageId, ref, registerMessage]);
152
+ return (_jsx("div", { ref: setElement, "data-message-id": messageId, "data-scroll-anchor": scrollAnchor ? 'true' : 'false', ...props }));
153
+ }
154
+ function MessageScrollerButton({ behavior = 'smooth', children, className, direction = 'end', onClick, render, tabIndex, type = 'button', ...props }) {
155
+ const controller = useController();
156
+ const store = controller.scrollableStore;
157
+ const subscribe = React.useCallback((listener) => store.subscribe(listener), [store]);
158
+ const getActive = React.useCallback(() => {
159
+ const snapshot = store.getSnapshot();
160
+ return direction === 'start' ? snapshot.start : snapshot.end;
161
+ }, [direction, store]);
162
+ const active = React.useSyncExternalStore(subscribe, getActive, getActive);
163
+ const handleClick = (event) => {
164
+ if (!active)
165
+ return;
166
+ onClick?.(event);
167
+ if (event.defaultPrevented)
168
+ return;
169
+ event.currentTarget.blur();
170
+ if (direction === 'start')
171
+ controller.scrollToStart({ behavior });
172
+ else
173
+ controller.scrollToEnd({ behavior });
174
+ };
175
+ const mergedProps = {
176
+ type,
177
+ className,
178
+ inert: active ? undefined : true,
179
+ tabIndex: active ? tabIndex : -1,
180
+ 'data-active': active ? 'true' : 'false',
181
+ onClick: handleClick,
182
+ children: children ?? _jsxs("span", { children: ["Scroll to ", direction] }),
183
+ ...props,
184
+ };
185
+ const state = { active, direction };
186
+ if (!render)
187
+ return React.createElement('button', mergedProps);
188
+ if (typeof render === 'function')
189
+ return render(mergedProps, state);
190
+ if (!React.isValidElement(render))
191
+ return null;
192
+ const renderProps = render.props;
193
+ return React.cloneElement(render, {
194
+ ...mergedProps,
195
+ className: [renderProps.className, className].filter(Boolean).join(' '),
196
+ children,
197
+ });
198
+ }
199
+ function useMessageScroller() {
200
+ const controller = useController();
201
+ return React.useMemo(() => ({
202
+ scrollToEnd: controller.scrollToEnd,
203
+ scrollToMessage: controller.scrollToMessage,
204
+ scrollToStart: controller.scrollToStart,
205
+ }), [controller]);
206
+ }
207
+ function useMessageScrollerScrollable() {
208
+ const store = useController().scrollableStore;
209
+ const subscribe = React.useCallback((listener) => store.subscribe(listener), [store]);
210
+ return React.useSyncExternalStore(subscribe, store.getSnapshot, store.getSnapshot);
211
+ }
212
+ function useMessageScrollerVisibility() {
213
+ const controller = useController();
214
+ const store = controller.visibilityStore;
215
+ const subscribe = React.useCallback((listener) => store.subscribe(listener, () => controller.observeVisibility(), () => controller.unobserveVisibility()), [controller, store]);
216
+ return React.useSyncExternalStore(subscribe, store.getSnapshot, store.getSnapshot);
217
+ }
218
+ const MessageScroller = {
219
+ Provider: MessageScrollerProvider,
220
+ Root: MessageScrollerRoot,
221
+ Viewport: MessageScrollerViewport,
222
+ Content: MessageScrollerContent,
223
+ Item: MessageScrollerItem,
224
+ Button: MessageScrollerButton,
225
+ };
226
+ export { MessageScroller, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, };
@@ -1,9 +1,9 @@
1
- import { MessageScroller as MessageScrollerPrimitive, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility } from '@shadcn/react/message-scroller';
2
1
  import * as React from 'react';
3
2
  import { Button } from './button';
3
+ import { MessageScroller as MessageScrollerPrimitive, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility } from './message-scroller-primitive';
4
4
  declare function MessageScrollerProvider(props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>): import("react/jsx-runtime").JSX.Element;
5
5
  declare function MessageScroller({ className, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
6
- declare function MessageScrollerViewport({ className, ref, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>): import("react/jsx-runtime").JSX.Element;
6
+ declare function MessageScrollerViewport({ className, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>): import("react/jsx-runtime").JSX.Element;
7
7
  declare function MessageScrollerContent({ className, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
8
8
  declare function MessageScrollerItem({ className, scrollAnchor, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Item>): import("react/jsx-runtime").JSX.Element;
9
9
  declare function MessageScrollerButton({ direction, className, children, render, variant, size, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Button> & Pick<React.ComponentProps<typeof Button>, 'variant' | 'size'>): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"message-scroller.d.ts","sourceRoot":"","sources":["../../../src/components/ui/message-scroller.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,IAAI,wBAAwB,EAC3C,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC7B,MAAM,gCAAgC,CAAA;AAEvC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAGjC,iBAAS,uBAAuB,CAC9B,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,2CAGtE;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,IAAI,CAAC,2CAW5D;AAED,iBAAS,uBAAuB,CAAC,EAC/B,SAAS,EACT,GAAG,EACH,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,2CAyBhE;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,OAAO,CAAC,2CAQ/D;AAED,iBAAS,mBAAmB,CAAC,EAC3B,SAAS,EACT,YAAoB,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,IAAI,CAAC,2CAY5D;AAED,iBAAS,qBAAqB,CAAC,EAC7B,SAAiB,EACjB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,OAAqB,EACrB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,MAAM,CAAC,GAC7D,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAyB9D;AAED,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,GAC7B,CAAA"}
1
+ {"version":3,"file":"message-scroller.d.ts","sourceRoot":"","sources":["../../../src/components/ui/message-scroller.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EACL,eAAe,IAAI,wBAAwB,EAC3C,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC7B,MAAM,8BAA8B,CAAA;AAErC,iBAAS,uBAAuB,CAC9B,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,2CAGtE;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,IAAI,CAAC,2CAW5D;AAED,iBAAS,uBAAuB,CAAC,EAC/B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,2CAWhE;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,OAAO,CAAC,2CAQ/D;AAED,iBAAS,mBAAmB,CAAC,EAC3B,SAAS,EACT,YAAoB,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,IAAI,CAAC,2CAY5D;AAED,iBAAS,qBAAqB,CAAC,EAC7B,SAAiB,EACjB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,OAAqB,EACrB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,MAAM,CAAC,GAC7D,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,2CAyB9D;AAED,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,GAC7B,CAAA"}
@@ -1,29 +1,17 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { MessageScroller as MessageScrollerPrimitive, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, } from '@shadcn/react/message-scroller';
4
3
  import { ArrowDown } from 'lucide-react';
5
- import * as React from 'react';
6
4
  import { cn } from '../../lib/utils';
7
5
  import { Button } from './button';
8
- import { useMessageScrollerLayoutStability } from './message-scroller-layout-stability';
6
+ import { MessageScroller as MessageScrollerPrimitive, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, } from './message-scroller-primitive';
9
7
  function MessageScrollerProvider(props) {
10
8
  return _jsx(MessageScrollerPrimitive.Provider, { ...props });
11
9
  }
12
10
  function MessageScroller({ className, ...props }) {
13
11
  return (_jsx(MessageScrollerPrimitive.Root, { "data-slot": "message-scroller", className: cn('group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden', className), ...props }));
14
12
  }
15
- function MessageScrollerViewport({ className, ref, ...props }) {
16
- const viewportRef = React.useRef(null);
17
- const { scrollToEnd } = useMessageScroller();
18
- useMessageScrollerLayoutStability(viewportRef, scrollToEnd);
19
- const setViewportRef = React.useCallback((element) => {
20
- viewportRef.current = element;
21
- if (typeof ref === 'function')
22
- ref(element);
23
- else if (ref)
24
- ref.current = element;
25
- }, [ref]);
26
- return (_jsx(MessageScrollerPrimitive.Viewport, { ref: setViewportRef, "data-slot": "message-scroller-viewport", className: cn('message-scroller-viewport size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [contain:content] [scrollbar-gutter:stable]', className), ...props }));
13
+ function MessageScrollerViewport({ className, ...props }) {
14
+ return (_jsx(MessageScrollerPrimitive.Viewport, { "data-slot": "message-scroller-viewport", className: cn('message-scroller-viewport size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [contain:content] [scrollbar-gutter:stable]', className), ...props }));
27
15
  }
28
16
  function MessageScrollerContent({ className, ...props }) {
29
17
  return (_jsx(MessageScrollerPrimitive.Content, { "data-slot": "message-scroller-content", className: cn('flex h-max min-h-full flex-col', className), ...props }));
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import { ButtonGroup } from './button-group';
3
+ import { type IconButtonProps, type IconButtonSize } from './icon-button';
4
+ export interface NavigationButtonGroupProps extends Omit<React.ComponentProps<typeof ButtonGroup>, 'children' | 'orientation'> {
5
+ canGoBack?: boolean;
6
+ canGoForward?: boolean;
7
+ onBack: () => void;
8
+ onForward: () => void;
9
+ backLabel?: string;
10
+ forwardLabel?: string;
11
+ size?: IconButtonSize;
12
+ variant?: Extract<IconButtonProps['variant'], 'ghost' | 'outline'>;
13
+ }
14
+ declare function NavigationButtonGroup({ canGoBack, canGoForward, onBack, onForward, backLabel, forwardLabel, size, variant, 'aria-label': ariaLabel, ...props }: NavigationButtonGroupProps): import("react/jsx-runtime").JSX.Element;
15
+ export { NavigationButtonGroup };
16
+ //# sourceMappingURL=navigation-button-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation-button-group.d.ts","sourceRoot":"","sources":["../../../src/components/ui/navigation-button-group.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAA;AAEtB,MAAM,WAAW,0BACf,SAAQ,IAAI,CACV,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EACxC,UAAU,GAAG,aAAa,CAC3B;IACD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC,CAAA;CACnE;AAED,iBAAS,qBAAqB,CAAC,EAC7B,SAAgB,EAChB,YAAmB,EACnB,MAAM,EACN,SAAS,EACT,SAAqB,EACrB,YAA2B,EAC3B,IAAW,EACX,OAAiB,EACjB,YAAY,EAAE,SAAwB,EACtC,GAAG,KAAK,EACT,EAAE,0BAA0B,2CAyB5B;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAA"}
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
4
+ import { ButtonGroup } from './button-group';
5
+ import { IconButton, } from './icon-button';
6
+ function NavigationButtonGroup({ canGoBack = true, canGoForward = true, onBack, onForward, backLabel = 'Go back', forwardLabel = 'Go forward', size = 'sm', variant = 'ghost', 'aria-label': ariaLabel = 'Navigation', ...props }) {
7
+ return (_jsxs(ButtonGroup, { "aria-label": ariaLabel, orientation: "horizontal", ...props, children: [_jsx(IconButton, { label: backLabel, tooltip: true, size: size, variant: variant, disabled: !canGoBack, onClick: onBack, children: _jsx(ChevronLeftIcon, {}) }), _jsx(IconButton, { label: forwardLabel, tooltip: true, size: size, variant: variant, disabled: !canGoForward, onClick: onForward, children: _jsx(ChevronRightIcon, {}) })] }));
8
+ }
9
+ export { NavigationButtonGroup };
@@ -1,11 +1,18 @@
1
1
  import * as PopoverPrimitive from '@radix-ui/react-popover';
2
2
  import * as React from 'react';
3
+ import { type MaterialVariant } from './material';
3
4
  declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
4
5
  declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
5
- declare function PopoverContent({ className, align, sideOffset, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
6
+ declare function PopoverPortal({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Portal>): import("react/jsx-runtime").JSX.Element;
7
+ declare function PopoverClose({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Close>): import("react/jsx-runtime").JSX.Element;
8
+ declare function PopoverContent({ className, align, material, sideOffset, size, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content> & {
9
+ material?: MaterialVariant;
10
+ size?: 'content' | 'sm' | 'default' | 'lg';
11
+ }): import("react/jsx-runtime").JSX.Element;
6
12
  declare function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>): import("react/jsx-runtime").JSX.Element;
7
13
  declare function PopoverHeader({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
8
14
  declare function PopoverTitle({ className, ...props }: React.ComponentProps<'h2'>): import("react/jsx-runtime").JSX.Element;
9
15
  declare function PopoverDescription({ className, ...props }: React.ComponentProps<'p'>): import("react/jsx-runtime").JSX.Element;
10
- export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverHeader, PopoverTitle, PopoverDescription, };
16
+ declare function PopoverArrow({ className, ...props }: React.ComponentProps<typeof PopoverPrimitive.Arrow>): import("react/jsx-runtime").JSX.Element;
17
+ export { Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, PopoverHeader, PopoverDescription, PopoverPortal, PopoverTitle, PopoverTrigger, };
11
18
  //# sourceMappingURL=popover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/components/ui/popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,iBAAS,OAAO,CAAC,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC,2CAEpD;AAED,iBAAS,cAAc,CAAC,EACtB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,2CAEvD;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,KAAgB,EAChB,UAAc,EACd,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,2CAevD;AAED,iBAAS,aAAa,CAAC,EACrB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,2CAEtD;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ1E;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,2CAQxE;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,2CAQ3B;AAED,OAAO,EACL,OAAO,EACP,cAAc,EACd,cAAc,EACd,aAAa,EACb,aAAa,EACb,YAAY,EACZ,kBAAkB,GACnB,CAAA"}
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/components/ui/popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AAE3D,iBAAS,OAAO,CAAC,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC,2CAEpD;AAED,iBAAS,cAAc,CAAC,EACtB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,2CAEvD;AAED,iBAAS,aAAa,CAAC,EACrB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,2CAEtD;AAED,iBAAS,YAAY,CAAC,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC,2CAErD;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,KAAgB,EAChB,QAAoB,EACpB,UAAc,EACd,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,GAAG;IACzD,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAA;CAC3C,2CAsBA;AAED,iBAAS,aAAa,CAAC,EACrB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,MAAM,CAAC,2CAEtD;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ1E;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,2CAQxE;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,2CAQ3B;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC,2CAQrD;AAED,OAAO,EACL,OAAO,EACP,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,GACf,CAAA"}