@curvenote/theme-ui 1.0.1 → 2.0.1

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 (166) hide show
  1. package/dist/components/layout/app-layout.d.ts +1 -1
  2. package/dist/components/layout/app-layout.d.ts.map +1 -1
  3. package/dist/components/layout/app-layout.js +6 -5
  4. package/dist/components/layout/app-sidebar.d.ts.map +1 -1
  5. package/dist/components/layout/app-sidebar.js +10 -6
  6. package/dist/components/layout/article-layout.d.ts +1 -1
  7. package/dist/components/layout/article-layout.d.ts.map +1 -1
  8. package/dist/components/layout/article-layout.js +6 -7
  9. package/dist/components/layout/header.js +1 -1
  10. package/dist/components/layout/index.d.ts +1 -0
  11. package/dist/components/layout/index.d.ts.map +1 -1
  12. package/dist/components/layout/index.js +1 -0
  13. package/dist/components/layout/loading-bar.d.ts +8 -1
  14. package/dist/components/layout/loading-bar.d.ts.map +1 -1
  15. package/dist/components/layout/loading-bar.js +12 -4
  16. package/dist/components/layout/site-header.d.ts +6 -1
  17. package/dist/components/layout/site-header.d.ts.map +1 -1
  18. package/dist/components/layout/site-header.js +7 -4
  19. package/dist/components/layout/types.d.ts +6 -0
  20. package/dist/components/layout/types.d.ts.map +1 -1
  21. package/dist/components/providers/analytics-boundary.d.ts +18 -0
  22. package/dist/components/providers/analytics-boundary.d.ts.map +1 -0
  23. package/dist/components/providers/analytics-boundary.js +53 -0
  24. package/dist/components/providers/analytics-dev-log.d.ts +11 -0
  25. package/dist/components/providers/analytics-dev-log.d.ts.map +1 -0
  26. package/dist/components/providers/analytics-dev-log.js +46 -0
  27. package/dist/components/providers/analytics-dev-tray.d.ts +2 -0
  28. package/dist/components/providers/analytics-dev-tray.d.ts.map +1 -0
  29. package/dist/components/providers/analytics-dev-tray.js +56 -0
  30. package/dist/components/providers/article-versions-provider.d.ts +19 -0
  31. package/dist/components/providers/article-versions-provider.d.ts.map +1 -0
  32. package/dist/components/providers/article-versions-provider.js +13 -0
  33. package/dist/components/providers/curvenote-providers.d.ts +12 -13
  34. package/dist/components/providers/curvenote-providers.d.ts.map +1 -1
  35. package/dist/components/providers/curvenote-providers.js +20 -27
  36. package/dist/components/providers/design.d.ts +3 -33
  37. package/dist/components/providers/design.d.ts.map +1 -1
  38. package/dist/components/providers/design.js +64 -21
  39. package/dist/components/providers/index.d.ts +4 -2
  40. package/dist/components/providers/index.d.ts.map +1 -1
  41. package/dist/components/providers/index.js +3 -1
  42. package/dist/components/providers/lightbox-provider.d.ts +8 -0
  43. package/dist/components/providers/lightbox-provider.d.ts.map +1 -1
  44. package/dist/components/providers/lightbox-provider.js +28 -5
  45. package/dist/components/providers/overlay-depth.d.ts +16 -0
  46. package/dist/components/providers/overlay-depth.d.ts.map +1 -0
  47. package/dist/components/providers/overlay-depth.js +16 -0
  48. package/dist/components/providers/ping-boundary.d.ts +3 -1
  49. package/dist/components/providers/ping-boundary.d.ts.map +1 -1
  50. package/dist/components/providers/ping-boundary.js +7 -4
  51. package/dist/components/providers/platform-providers.d.ts +0 -7
  52. package/dist/components/providers/platform-providers.d.ts.map +1 -1
  53. package/dist/components/providers/platform-providers.js +0 -14
  54. package/dist/components/ui/abbreviations.d.ts +3 -1
  55. package/dist/components/ui/abbreviations.d.ts.map +1 -1
  56. package/dist/components/ui/abbreviations.js +13 -6
  57. package/dist/components/ui/accessibility-skip-to.d.ts +13 -3
  58. package/dist/components/ui/accessibility-skip-to.d.ts.map +1 -1
  59. package/dist/components/ui/accessibility-skip-to.js +4 -1
  60. package/dist/components/ui/arrow.d.ts +6 -0
  61. package/dist/components/ui/arrow.d.ts.map +1 -0
  62. package/dist/components/ui/arrow.js +15 -0
  63. package/dist/components/ui/article-actions-downloads.d.ts.map +1 -1
  64. package/dist/components/ui/article-actions-downloads.js +74 -7
  65. package/dist/components/ui/article-actions-dropdown.d.ts +2 -1
  66. package/dist/components/ui/article-actions-dropdown.d.ts.map +1 -1
  67. package/dist/components/ui/article-actions-dropdown.js +102 -21
  68. package/dist/components/ui/article-actions-share.d.ts +18 -0
  69. package/dist/components/ui/article-actions-share.d.ts.map +1 -1
  70. package/dist/components/ui/article-actions-share.js +38 -2
  71. package/dist/components/ui/article-actions.d.ts.map +1 -1
  72. package/dist/components/ui/article-actions.js +16 -3
  73. package/dist/components/ui/article-bar.d.ts +3 -1
  74. package/dist/components/ui/article-bar.d.ts.map +1 -1
  75. package/dist/components/ui/article-bar.js +19 -5
  76. package/dist/components/ui/article-card.js +1 -1
  77. package/dist/components/ui/author-popover.d.ts +2 -1
  78. package/dist/components/ui/author-popover.d.ts.map +1 -1
  79. package/dist/components/ui/author-popover.js +42 -7
  80. package/dist/components/ui/backmatter.d.ts.map +1 -1
  81. package/dist/components/ui/backmatter.js +23 -5
  82. package/dist/components/ui/banner.d.ts.map +1 -1
  83. package/dist/components/ui/banner.js +1 -1
  84. package/dist/components/ui/bibliography.d.ts +2 -2
  85. package/dist/components/ui/bibliography.d.ts.map +1 -1
  86. package/dist/components/ui/bibliography.js +10 -9
  87. package/dist/components/ui/button.d.ts +1 -1
  88. package/dist/components/ui/button.d.ts.map +1 -1
  89. package/dist/components/ui/button.js +2 -0
  90. package/dist/components/ui/calendar.d.ts +10 -0
  91. package/dist/components/ui/calendar.d.ts.map +1 -0
  92. package/dist/components/ui/calendar.js +85 -0
  93. package/dist/components/ui/citation.d.ts +2 -2
  94. package/dist/components/ui/citation.d.ts.map +1 -1
  95. package/dist/components/ui/citation.js +45 -15
  96. package/dist/components/ui/collapsible-backmatter-section.d.ts +28 -0
  97. package/dist/components/ui/collapsible-backmatter-section.d.ts.map +1 -0
  98. package/dist/components/ui/collapsible-backmatter-section.js +52 -0
  99. package/dist/components/ui/cookie-banner.d.ts +1 -1
  100. package/dist/components/ui/cookie-banner.d.ts.map +1 -1
  101. package/dist/components/ui/cookie-banner.js +9 -2
  102. package/dist/components/ui/document-outline.d.ts.map +1 -1
  103. package/dist/components/ui/document-outline.js +38 -20
  104. package/dist/components/ui/footer-links.d.ts.map +1 -1
  105. package/dist/components/ui/footer-links.js +4 -0
  106. package/dist/components/ui/frontmatter-badges.d.ts +15 -5
  107. package/dist/components/ui/frontmatter-badges.d.ts.map +1 -1
  108. package/dist/components/ui/frontmatter-badges.js +41 -15
  109. package/dist/components/ui/frontmatter.js +1 -1
  110. package/dist/components/ui/hash-link.d.ts +56 -0
  111. package/dist/components/ui/hash-link.d.ts.map +1 -0
  112. package/dist/components/ui/hash-link.js +83 -0
  113. package/dist/components/ui/image.d.ts +5 -2
  114. package/dist/components/ui/image.d.ts.map +1 -1
  115. package/dist/components/ui/image.js +10 -8
  116. package/dist/components/ui/index.d.ts +10 -2
  117. package/dist/components/ui/index.d.ts.map +1 -1
  118. package/dist/components/ui/index.js +9 -2
  119. package/dist/components/ui/keywords.d.ts +4 -0
  120. package/dist/components/ui/keywords.d.ts.map +1 -0
  121. package/dist/components/ui/keywords.js +18 -0
  122. package/dist/components/ui/label.d.ts +4 -0
  123. package/dist/components/ui/label.d.ts.map +1 -0
  124. package/dist/components/ui/label.js +6 -0
  125. package/dist/components/ui/license-description.d.ts.map +1 -1
  126. package/dist/components/ui/license-description.js +8 -5
  127. package/dist/components/ui/license-frontmatter.d.ts.map +1 -1
  128. package/dist/components/ui/license-frontmatter.js +14 -3
  129. package/dist/components/ui/lightbox-container.d.ts.map +1 -1
  130. package/dist/components/ui/lightbox-container.js +2 -2
  131. package/dist/components/ui/lightbox.d.ts +3 -1
  132. package/dist/components/ui/lightbox.d.ts.map +1 -1
  133. package/dist/components/ui/lightbox.js +155 -25
  134. package/dist/components/ui/link-card.d.ts +2 -1
  135. package/dist/components/ui/link-card.d.ts.map +1 -1
  136. package/dist/components/ui/link-card.js +2 -2
  137. package/dist/components/ui/pagination.d.ts +15 -0
  138. package/dist/components/ui/pagination.d.ts.map +1 -0
  139. package/dist/components/ui/pagination.js +31 -0
  140. package/dist/components/ui/popover.js +1 -1
  141. package/dist/components/ui/search.d.ts +2 -1
  142. package/dist/components/ui/search.d.ts.map +1 -1
  143. package/dist/components/ui/search.js +24 -8
  144. package/dist/components/ui/select.d.ts +16 -0
  145. package/dist/components/ui/select.d.ts.map +1 -0
  146. package/dist/components/ui/select.js +38 -0
  147. package/dist/components/ui/separator.js +1 -1
  148. package/dist/components/ui/sidebar.d.ts +2 -12
  149. package/dist/components/ui/sidebar.d.ts.map +1 -1
  150. package/dist/components/ui/sidebar.js +2 -34
  151. package/dist/components/ui/tooltip.d.ts +4 -2
  152. package/dist/components/ui/tooltip.d.ts.map +1 -1
  153. package/dist/components/ui/tooltip.js +5 -4
  154. package/dist/components/ui/types.d.ts +9 -8
  155. package/dist/components/ui/types.d.ts.map +1 -1
  156. package/dist/components/ui/types.js +1 -0
  157. package/dist/lib/dedupeAbbreviations.d.ts +10 -0
  158. package/dist/lib/dedupeAbbreviations.d.ts.map +1 -0
  159. package/dist/lib/dedupeAbbreviations.js +36 -0
  160. package/dist/lib/knownParts.d.ts +18 -0
  161. package/dist/lib/knownParts.d.ts.map +1 -1
  162. package/dist/lib/knownParts.js +38 -1
  163. package/package.json +12 -9
  164. package/dist/components/providers/types.d.ts +0 -30
  165. package/dist/components/providers/types.d.ts.map +0 -1
  166. package/dist/components/providers/types.js +0 -1
@@ -4,20 +4,149 @@ import { Dialog, DialogContent, DialogTitle, DialogDescription } from '@radix-ui
4
4
  import { X, ChevronLeft, ChevronRight, ZoomIn, ZoomOut, RotateCcw } from 'lucide-react';
5
5
  import { cn } from '../../lib/utils';
6
6
  import { Button } from './button';
7
+ import { useAnalytics } from '../providers/analytics-boundary';
7
8
  import { MyST } from 'myst-to-react';
8
9
  import { Picture } from './image';
9
- export function Lightbox({ isOpen, onClose, image, onNavigate, hasNext = false, hasPrev = false, showNavigation = true, showZoom = true, className, minZoom = 0.5, maxZoom = 7, }) {
10
+ function getLightboxImageProperties(image) {
11
+ const isVideo = image.src.endsWith('.mp4') || image.urlSource?.endsWith('.mp4');
12
+ return {
13
+ imageUrl: image.src,
14
+ imageAlt: image.alt,
15
+ hasCaption: Boolean(image.caption),
16
+ mediaType: isVideo ? 'video' : 'image',
17
+ };
18
+ }
19
+ export function Lightbox({ isOpen, onClose, image, onNavigate, hasNext = false, hasPrev = false, showNavigation = true, showZoom = true, className, minZoom = 0.5, maxZoom = 7, currentIndex, imageCount, }) {
20
+ const capture = useAnalytics();
10
21
  const [zoomLevel, setZoomLevel] = React.useState(1);
22
+ const zoomLevelRef = React.useRef(zoomLevel);
23
+ zoomLevelRef.current = zoomLevel;
11
24
  const [isDragging, setIsDragging] = React.useState(false);
12
25
  const [dragOffset, setDragOffset] = React.useState({ x: 0, y: 0 });
13
26
  const [imageLoaded, setImageLoaded] = React.useState(false);
14
27
  const imageRef = React.useRef(null);
15
28
  const containerRef = React.useRef(null);
29
+ const captionExpandedRef = React.useRef(false);
30
+ const mediaLoadedRef = React.useRef(null);
31
+ /** At most one zoom-related analytics event per image; intent is session signal, not per gesture. */
32
+ const zoomAnalyticsSentForImageRef = React.useRef(false);
33
+ /** At most one pan-related analytics event per image; intent is session signal, not per gesture. */
34
+ const panAnalyticsSentForImageRef = React.useRef(false);
35
+ const lightboxContext = React.useMemo(() => ({
36
+ currentIndex,
37
+ imageCount,
38
+ ...getLightboxImageProperties(image),
39
+ /** Full-screen lightbox is one layer above the opener's depth. */
40
+ overlayDepth: (image.openingOverlayDepth ?? 0) + 1,
41
+ }), [currentIndex, image, imageCount]);
42
+ const captureClose = React.useCallback((closeMethod) => {
43
+ capture('content_lightbox_closed', {
44
+ surface: 'content',
45
+ closeMethod,
46
+ ...lightboxContext,
47
+ });
48
+ }, [capture, lightboxContext]);
49
+ const handleClose = React.useCallback((closeMethod) => {
50
+ captureClose(closeMethod);
51
+ onClose();
52
+ }, [captureClose, onClose]);
53
+ const handleNavigate = React.useCallback((direction, navigationMethod) => {
54
+ capture('content_lightbox_navigated', {
55
+ surface: 'content',
56
+ direction,
57
+ navigationMethod,
58
+ ...lightboxContext,
59
+ });
60
+ onNavigate?.(direction);
61
+ }, [capture, lightboxContext, onNavigate]);
62
+ const captureZoom = React.useCallback((zoomMethod, nextZoom) => {
63
+ capture('content_lightbox_zoom_changed', {
64
+ surface: 'content',
65
+ zoomMethod,
66
+ zoomLevel: nextZoom,
67
+ ...lightboxContext,
68
+ });
69
+ }, [capture, lightboxContext]);
70
+ const captureZoomReset = React.useCallback((zoomMethod) => {
71
+ capture('content_lightbox_zoom_reset', {
72
+ surface: 'content',
73
+ zoomMethod,
74
+ ...lightboxContext,
75
+ });
76
+ }, [capture, lightboxContext]);
77
+ const capturePan = React.useCallback((panMethod, offset) => {
78
+ capture('content_lightbox_pan_changed', {
79
+ surface: 'content',
80
+ panMethod,
81
+ panOffsetX: offset.x,
82
+ panOffsetY: offset.y,
83
+ zoomLevel: zoomLevelRef.current,
84
+ ...lightboxContext,
85
+ });
86
+ }, [capture, lightboxContext]);
87
+ const emitZoomAnalyticsOncePerImage = React.useCallback((emit) => {
88
+ if (zoomAnalyticsSentForImageRef.current)
89
+ return;
90
+ zoomAnalyticsSentForImageRef.current = true;
91
+ emit();
92
+ }, []);
93
+ const emitPanAnalyticsOncePerImage = React.useCallback((emit) => {
94
+ if (panAnalyticsSentForImageRef.current)
95
+ return;
96
+ panAnalyticsSentForImageRef.current = true;
97
+ emit();
98
+ }, []);
99
+ const updateZoom = React.useCallback((zoomMethod, updater) => {
100
+ const prev = zoomLevelRef.current;
101
+ const next = updater(prev);
102
+ zoomLevelRef.current = next;
103
+ const isReset = zoomMethod === 'keyboard_reset' || zoomMethod === 'reset_button';
104
+ if (isReset) {
105
+ if (prev !== 1 || next !== 1) {
106
+ emitZoomAnalyticsOncePerImage(() => captureZoomReset(zoomMethod));
107
+ }
108
+ }
109
+ else if (next !== prev) {
110
+ emitZoomAnalyticsOncePerImage(() => captureZoom(zoomMethod, next));
111
+ }
112
+ setZoomLevel(next);
113
+ }, [captureZoom, captureZoomReset, emitZoomAnalyticsOncePerImage]);
114
+ const handleCaptionExpand = React.useCallback(() => {
115
+ if (captionExpandedRef.current)
116
+ return;
117
+ captionExpandedRef.current = true;
118
+ capture('content_lightbox_caption_expanded', {
119
+ surface: 'content',
120
+ ...lightboxContext,
121
+ });
122
+ }, [capture, lightboxContext]);
123
+ const handleMediaLoaded = React.useCallback(() => {
124
+ if (mediaLoadedRef.current === image.src)
125
+ return;
126
+ mediaLoadedRef.current = image.src;
127
+ setImageLoaded(true);
128
+ capture('content_lightbox_media_loaded', {
129
+ surface: 'content',
130
+ ...lightboxContext,
131
+ });
132
+ }, [capture, image.src, lightboxContext]);
133
+ // New lightbox open: allow one zoom/pan sample again (same image may be revisited after close).
134
+ React.useEffect(() => {
135
+ if (isOpen) {
136
+ zoomAnalyticsSentForImageRef.current = false;
137
+ panAnalyticsSentForImageRef.current = false;
138
+ }
139
+ }, [isOpen]);
16
140
  // Reset zoom and position when image changes
17
141
  React.useEffect(() => {
142
+ zoomLevelRef.current = 1;
143
+ zoomAnalyticsSentForImageRef.current = false;
144
+ panAnalyticsSentForImageRef.current = false;
18
145
  setZoomLevel(1);
19
146
  setDragOffset({ x: 0, y: 0 });
20
147
  setImageLoaded(false);
148
+ captionExpandedRef.current = false;
149
+ mediaLoadedRef.current = null;
21
150
  }, [image.src]);
22
151
  // Handle wheel events with passive listener handling
23
152
  React.useEffect(() => {
@@ -26,64 +155,61 @@ export function Lightbox({ isOpen, onClose, image, onNavigate, hasNext = false,
26
155
  const handleWheelEvent = (e) => {
27
156
  e.preventDefault();
28
157
  e.stopPropagation();
29
- // Immediate zoom without timeout
30
158
  const delta = e.deltaY > 0 ? 0.98 : 1.02;
31
- setZoomLevel((prev) => {
32
- const newZoom = prev * delta;
33
- return Math.max(minZoom, Math.min(newZoom, maxZoom));
34
- });
159
+ const prev = zoomLevelRef.current;
160
+ const newZoom = Math.max(minZoom, Math.min(prev * delta, maxZoom));
161
+ zoomLevelRef.current = newZoom;
162
+ if (newZoom !== prev) {
163
+ emitZoomAnalyticsOncePerImage(() => captureZoom('wheel', newZoom));
164
+ }
165
+ setZoomLevel(newZoom);
35
166
  };
36
- // Add wheel event listener with passive: false
37
167
  document.addEventListener('wheel', handleWheelEvent, { passive: false });
38
168
  return () => {
39
169
  document.removeEventListener('wheel', handleWheelEvent);
40
170
  };
41
- }, [isOpen, showZoom]);
171
+ }, [captureZoom, emitZoomAnalyticsOncePerImage, isOpen, maxZoom, minZoom, showZoom]);
42
172
  // Handle keyboard navigation
43
173
  React.useEffect(() => {
44
174
  const handleKeyDown = (e) => {
45
175
  if (!isOpen)
46
176
  return;
47
177
  switch (e.key) {
48
- case 'Escape':
49
- onClose();
50
- break;
51
178
  case 'ArrowLeft':
52
179
  if (hasPrev && onNavigate) {
53
- onNavigate('prev');
180
+ handleNavigate('prev', 'keyboard');
54
181
  }
55
182
  break;
56
183
  case 'ArrowRight':
57
184
  if (hasNext && onNavigate) {
58
- onNavigate('next');
185
+ handleNavigate('next', 'keyboard');
59
186
  }
60
187
  break;
61
188
  case 'PageUp':
62
189
  case 'PageDown':
63
190
  case 'ArrowUp':
64
191
  case 'ArrowDown':
65
- // Stops scrolling the page
66
192
  e.preventDefault();
67
193
  break;
68
194
  case '=':
69
195
  case '+':
70
196
  e.preventDefault();
71
- setZoomLevel((prev) => Math.min(prev * 1.2, maxZoom));
197
+ updateZoom('keyboard_zoom_in', (prev) => Math.min(prev * 1.2, maxZoom));
72
198
  break;
73
199
  case '-':
74
200
  e.preventDefault();
75
- setZoomLevel((prev) => Math.max(prev / 1.2, minZoom));
201
+ updateZoom('keyboard_zoom_out', (prev) => Math.max(prev / 1.2, minZoom));
76
202
  break;
77
203
  case '0':
78
204
  e.preventDefault();
79
- setZoomLevel(1);
80
205
  setDragOffset({ x: 0, y: 0 });
206
+ updateZoom('keyboard_reset', () => 1);
81
207
  break;
82
208
  }
83
209
  };
84
210
  document.addEventListener('keydown', handleKeyDown);
85
211
  return () => document.removeEventListener('keydown', handleKeyDown);
86
- }, [isOpen, hasPrev, hasNext, onNavigate, onClose]);
212
+ }, [handleNavigate, isOpen, hasPrev, hasNext, maxZoom, minZoom, onNavigate, updateZoom]);
87
213
  // Handle mouse drag for panning
88
214
  const [dragStart, setDragStart] = React.useState({ x: 0, y: 0 });
89
215
  const handleMouseDown = (e) => {
@@ -98,21 +224,25 @@ export function Lightbox({ isOpen, onClose, image, onNavigate, hasNext = false,
98
224
  // if (!isDragging || zoomLevel <= 1) return;
99
225
  if (!isDragging)
100
226
  return;
101
- setDragOffset({
227
+ const offset = {
102
228
  x: e.clientX - dragStart.x,
103
229
  y: e.clientY - dragStart.y,
104
- });
230
+ };
231
+ setDragOffset(offset);
232
+ emitPanAnalyticsOncePerImage(() => capturePan('drag', offset));
105
233
  };
106
234
  const handleMouseUp = () => {
107
235
  setIsDragging(false);
108
236
  };
109
237
  const resetZoom = () => {
110
- setZoomLevel(1);
111
238
  setDragOffset({ x: 0, y: 0 });
239
+ updateZoom('reset_button', () => 1);
112
240
  };
113
- // Check if this is a video
114
- const isVideo = image.src.endsWith('.mp4') || image.urlSource?.endsWith('.mp4');
115
- return (_jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: _jsxs(DialogContent, { className: cn('flex fixed inset-0 z-50 justify-center items-center p-4 bg-black/90', className), onPointerDownOutside: onClose, onEscapeKeyDown: onClose, onTouchStart: (e) => e.preventDefault(), onTouchMove: (e) => e.preventDefault(), children: [_jsx(DialogTitle, { className: "sr-only", children: image.alt || 'Image viewer' }), _jsx(DialogDescription, { className: "sr-only", children: image.alt ? `Viewing ${image.alt}` : 'Image viewer with zoom and navigation controls' }), _jsx(Button, { variant: "ghost", size: "icon", className: "absolute top-4 right-4 z-10 text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: onClose, children: _jsx(X, { className: "w-6 h-6" }) }), showNavigation && (hasPrev || hasNext) && (_jsxs(_Fragment, { children: [hasPrev && (_jsx(Button, { variant: "ghost", size: "icon", className: "absolute left-4 top-1/2 z-10 text-white -translate-y-1/2 cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => onNavigate?.('prev'), children: _jsx(ChevronLeft, { className: "w-8 h-8" }) })), hasNext && (_jsx(Button, { variant: "ghost", size: "icon", className: "absolute right-4 top-1/2 z-10 text-white -translate-y-1/2 cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => onNavigate?.('next'), children: _jsx(ChevronRight, { className: "w-8 h-8" }) }))] })), showZoom && !isVideo && (_jsxs("div", { className: "flex absolute top-4 left-4 z-10 gap-2", children: [_jsx(Button, { variant: "ghost", size: "icon", className: "text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => setZoomLevel((prev) => Math.min(prev * 1.2, 5)), children: _jsx(ZoomIn, { className: "w-5 h-5" }) }), _jsx(Button, { variant: "ghost", size: "icon", className: "text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => setZoomLevel((prev) => Math.max(prev / 1.2, 0.1)), children: _jsx(ZoomOut, { className: "w-5 h-5" }) }), _jsx(Button, { variant: "ghost", size: "icon", className: "text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: resetZoom, children: _jsx(RotateCcw, { className: "w-5 h-5" }) })] })), _jsxs("div", { ref: containerRef, className: "flex overflow-hidden relative justify-center items-center w-full h-full max-h-screen", onMouseDown: !isVideo ? handleMouseDown : undefined, onMouseMove: !isVideo ? handleMouseMove : undefined, onMouseUp: !isVideo ? handleMouseUp : undefined, onMouseLeave: !isVideo ? handleMouseUp : undefined, onTouchStart: (e) => e.preventDefault(), onTouchMove: (e) => e.preventDefault(), children: [_jsx(Picture, { ref: imageRef, src: image.src, srcOptimized: image.srcOptimized, urlSource: image.urlSource, alt: image.alt, className: cn('object-contain max-w-full max-h-full select-none', {
241
+ const isVideo = getLightboxImageProperties(image).mediaType === 'video';
242
+ return (_jsx(Dialog, { open: isOpen, onOpenChange: (open) => {
243
+ if (!open)
244
+ onClose();
245
+ }, children: _jsxs(DialogContent, { className: cn('flex fixed inset-0 z-50 justify-center items-center p-4 bg-black/90', className), onPointerDownOutside: () => handleClose('backdrop'), onEscapeKeyDown: () => handleClose('escape'), onTouchStart: (e) => e.preventDefault(), onTouchMove: (e) => e.preventDefault(), children: [_jsx(DialogTitle, { className: "sr-only", children: image.alt || 'Image viewer' }), _jsx(DialogDescription, { className: "sr-only", children: image.alt ? `Viewing ${image.alt}` : 'Image viewer with zoom and navigation controls' }), _jsx(Button, { variant: "ghost", size: "icon", className: "absolute top-4 right-4 z-10 text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => handleClose('close_button'), children: _jsx(X, { className: "w-6 h-6" }) }), showNavigation && (hasPrev || hasNext) && (_jsxs(_Fragment, { children: [hasPrev && (_jsx(Button, { variant: "ghost", size: "icon", className: "absolute left-4 top-1/2 z-10 text-white -translate-y-1/2 cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => handleNavigate('prev', 'button'), children: _jsx(ChevronLeft, { className: "w-8 h-8" }) })), hasNext && (_jsx(Button, { variant: "ghost", size: "icon", className: "absolute right-4 top-1/2 z-10 text-white -translate-y-1/2 cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => handleNavigate('next', 'button'), children: _jsx(ChevronRight, { className: "w-8 h-8" }) }))] })), showZoom && !isVideo && (_jsxs("div", { className: "flex absolute top-4 left-4 z-10 gap-2", children: [_jsx(Button, { variant: "ghost", size: "icon", className: "text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => updateZoom('zoom_in_button', (prev) => Math.min(prev * 1.2, maxZoom)), children: _jsx(ZoomIn, { className: "w-5 h-5" }) }), _jsx(Button, { variant: "ghost", size: "icon", className: "text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: () => updateZoom('zoom_out_button', (prev) => Math.max(prev / 1.2, minZoom)), children: _jsx(ZoomOut, { className: "w-5 h-5" }) }), _jsx(Button, { variant: "ghost", size: "icon", className: "text-white cursor-pointer hover:bg-white/10 hover:text-white", onClick: resetZoom, children: _jsx(RotateCcw, { className: "w-5 h-5" }) })] })), _jsxs("div", { ref: containerRef, className: "flex overflow-hidden relative justify-center items-center w-full h-full max-h-screen", onMouseDown: !isVideo ? handleMouseDown : undefined, onMouseMove: !isVideo ? handleMouseMove : undefined, onMouseUp: !isVideo ? handleMouseUp : undefined, onMouseLeave: !isVideo ? handleMouseUp : undefined, onTouchStart: (e) => e.preventDefault(), onTouchMove: (e) => e.preventDefault(), children: [_jsx(Picture, { ref: imageRef, src: image.src, srcOptimized: image.srcOptimized, urlSource: image.urlSource, alt: image.alt, className: cn('object-contain max-w-full max-h-full select-none', {
116
246
  'cursor-grab active:cursor-grabbing': !isVideo,
117
247
  'opacity-0': !imageLoaded,
118
248
  'opacity-100': imageLoaded,
@@ -125,5 +255,5 @@ export function Lightbox({ isOpen, onClose, image, onNavigate, hasNext = false,
125
255
  : {
126
256
  maxHeight: 'calc(100vh - 8rem)', // Account for padding and controls
127
257
  maxWidth: 'calc(100vw - 2rem)', // Account for padding
128
- }, onLoad: () => setImageLoaded(true), onLoadedData: () => setImageLoaded(true) }), !imageLoaded && (_jsx("div", { className: "flex absolute inset-0 justify-center items-center", children: _jsx("div", { className: "w-8 h-8 rounded-full border-2 animate-spin border-white/20 border-t-white" }) }))] }), image.caption && (_jsx("div", { className: "absolute right-4 bottom-4 left-4 z-10", children: _jsx("div", { className: "px-4 py-2 mx-auto max-w-6xl text-sm text-white rounded-lg backdrop-blur-sm group bg-black/80 prose prose-invert", children: _jsx("div", { className: "overflow-hidden transition-all duration-750 max-h-[3rem] group-hover:max-h-[50rem]", children: typeof image.caption === 'string' ? image.caption : _jsx(MyST, { ast: image.caption }) }) }) })), showZoom && !isVideo && zoomLevel !== 1 && (_jsxs("div", { className: "absolute right-4 bottom-4 z-10 px-3 py-1 text-sm text-white rounded-sm backdrop-blur-sm bg-black/50", children: [Math.round(zoomLevel * 100), "%"] }))] }) }));
258
+ }, onLoad: handleMediaLoaded, onLoadedData: handleMediaLoaded }), !imageLoaded && (_jsx("div", { className: "flex absolute inset-0 justify-center items-center", children: _jsx("div", { className: "w-8 h-8 rounded-full border-2 animate-spin border-white/20 border-t-white" }) }))] }), image.caption && (_jsx("div", { className: "absolute right-4 bottom-4 left-4 z-10", children: _jsx("div", { className: "px-4 py-2 mx-auto max-w-6xl text-sm text-white rounded-lg backdrop-blur-sm group bg-black/80 prose prose-invert", onMouseEnter: handleCaptionExpand, children: _jsx("div", { className: "overflow-hidden transition-all duration-750 max-h-[3rem] group-hover:max-h-[50rem]", children: typeof image.caption === 'string' ? image.caption : _jsx(MyST, { ast: image.caption }) }) }) })), showZoom && !isVideo && zoomLevel !== 1 && (_jsxs("div", { className: "absolute right-4 bottom-4 z-10 px-3 py-1 text-sm text-white rounded-sm backdrop-blur-sm bg-black/50", children: [Math.round(zoomLevel * 100), "%"] }))] }) }));
129
259
  }
@@ -3,13 +3,14 @@ declare const linkCardVariants: (props?: ({
3
3
  variant?: "default" | null | undefined;
4
4
  size?: "default" | "lg" | null | undefined;
5
5
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
- export declare function LinkCard({ url, title, internal, loading, description, thumbnail, variant, size, }: {
6
+ export declare function LinkCard({ url, title, internal, loading, description, thumbnail, variant, size, onLinkClick, }: {
7
7
  url: string;
8
8
  internal?: boolean;
9
9
  loading?: boolean;
10
10
  title: React.ReactNode;
11
11
  description?: React.ReactNode;
12
12
  thumbnail?: string | null;
13
+ onLinkClick?: () => void;
13
14
  } & VariantProps<typeof linkCardVariants>): import("react/jsx-runtime").JSX.Element;
14
15
  export {};
15
16
  //# sourceMappingURL=link-card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"link-card.d.ts","sourceRoot":"","sources":["../../../src/components/ui/link-card.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,QAAA,MAAM,gBAAgB;;;8EAcpB,CAAC;AAEH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,KAAK,EACL,QAAgB,EAChB,OAAe,EACf,WAAW,EACX,SAAS,EACT,OAAO,EACP,IAAI,GACL,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,2CAmDxC"}
1
+ {"version":3,"file":"link-card.d.ts","sourceRoot":"","sources":["../../../src/components/ui/link-card.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,QAAA,MAAM,gBAAgB;;;8EAcpB,CAAC;AAEH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,KAAK,EACL,QAAgB,EAChB,OAAe,EACf,WAAW,EACX,SAAS,EACT,OAAO,EACP,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,2CAsDxC"}
@@ -18,11 +18,11 @@ const linkCardVariants = cva('overflow-hidden rounded hover-card-content', {
18
18
  size: 'default',
19
19
  },
20
20
  });
21
- export function LinkCard({ url, title, internal = false, loading = false, description, thumbnail, variant, size, }) {
21
+ export function LinkCard({ url, title, internal = false, loading = false, description, thumbnail, variant, size, onLinkClick, }) {
22
22
  const Link = useLinkProvider();
23
23
  const baseurl = useBaseurl();
24
24
  const to = internal ? withBaseurl(url, baseurl) : url;
25
25
  return (_jsxs("div", { className: cn(linkCardVariants({ variant, size }), {
26
26
  'animate-pulse': loading,
27
- }), children: [_jsxs("div", { className: "group", children: [!loading && thumbnail && (_jsx(Link, { to: to, prefetch: internal ? 'intent' : 'none', target: internal ? '_self' : '_blank', className: "block overflow-hidden h-[150px] border-b border-gray-200", children: _jsx("img", { src: thumbnail, className: "w-full h-[150px] object-cover object-center object-middle m-0 border-b border-gray-200 transition-transform duration-500 ease-in-out group-hover:scale-125" }) })), loading && (_jsx("div", { className: "animate-pulse bg-slate-100 dark:bg-slate-800 w-full h-[150px]" })), internal && (_jsx(Link, { to: to, className: "block px-3 mt-3 text-sm font-bold text-black hover:underline", prefetch: "intent", children: title })), !internal && (_jsxs("a", { href: to, className: "block px-3 py-2 text-sm font-bold text-black bg-gray-100 border-b border-gray-200 hover:underline", target: "_blank", rel: "noreferrer", children: [_jsx(ExternalLinkIcon, { width: "1rem", height: "1rem", className: "float-right" }), title] }))] }), !loading && description && _jsx("div", { className: "p-3 max-w-none text-sm prose", children: description })] }));
27
+ }), children: [_jsxs("div", { className: "group", children: [!loading && thumbnail && (_jsx(Link, { to: to, prefetch: internal ? 'intent' : 'none', target: internal ? '_self' : '_blank', className: "block overflow-hidden h-[150px] border-b border-gray-200", onClick: () => onLinkClick?.(), children: _jsx("img", { src: thumbnail, className: "w-full h-[150px] object-cover object-center object-middle m-0 border-b border-gray-200 transition-transform duration-500 ease-in-out group-hover:scale-125" }) })), loading && (_jsx("div", { className: "animate-pulse bg-slate-100 dark:bg-slate-800 w-full h-[150px]" })), internal && (_jsx(Link, { to: to, className: "block px-3 mt-3 text-sm font-bold text-black hover:underline", prefetch: "intent", onClick: () => onLinkClick?.(), children: title })), !internal && (_jsxs("a", { href: to, className: "block px-3 py-2 text-sm font-bold text-black bg-gray-100 border-b border-gray-200 hover:underline", target: "_blank", rel: "noreferrer", onClick: () => onLinkClick?.(), children: [_jsx(ExternalLinkIcon, { width: "1rem", height: "1rem", className: "float-right" }), title] }))] }), !loading && description && _jsx("div", { className: "p-3 max-w-none text-sm prose", children: description })] }));
28
28
  }
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+ declare function Pagination({ className, ...props }: React.ComponentProps<'nav'>): import("react/jsx-runtime").JSX.Element;
3
+ declare function PaginationContent({ className, ...props }: React.ComponentProps<'ul'>): import("react/jsx-runtime").JSX.Element;
4
+ declare function PaginationItem({ className, ...props }: React.ComponentProps<'li'>): import("react/jsx-runtime").JSX.Element;
5
+ type PaginationLinkProps = {
6
+ isActive?: boolean;
7
+ asChild?: boolean;
8
+ size?: 'default' | 'icon';
9
+ } & React.ComponentProps<'a'>;
10
+ declare function PaginationLink({ className, isActive, size, asChild, ...props }: PaginationLinkProps): import("react/jsx-runtime").JSX.Element;
11
+ declare function PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>): import("react/jsx-runtime").JSX.Element;
12
+ declare function PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>): import("react/jsx-runtime").JSX.Element;
13
+ declare function PaginationEllipsis({ className, ...props }: React.ComponentProps<'span'>): import("react/jsx-runtime").JSX.Element;
14
+ export { Pagination, PaginationContent, PaginationLink, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis, };
15
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/components/ui/pagination.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAUvE;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,2CAQ7E;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,2CAE1E;AAED,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC3B,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AAE9B,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,QAAQ,EACR,IAAgB,EAChB,OAAe,EACf,GAAG,KAAK,EACT,EAAE,mBAAmB,2CAoBrB;AAED,iBAAS,kBAAkB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,2CAY/F;AAED,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,2CAY3F;AAED,iBAAS,kBAAkB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,2CAYhF;AAED,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,GACnB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { Slot } from '@radix-ui/react-slot';
4
+ import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
5
+ import { cn } from '../../lib/utils';
6
+ const paginationLinkBase = 'inline-flex items-center justify-center gap-0.5 whitespace-nowrap rounded-md text-xs font-medium tabular-nums transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-3.5 [&_svg]:shrink-0';
7
+ function Pagination({ className, ...props }) {
8
+ return (_jsx("nav", { role: "navigation", "aria-label": "pagination", "data-slot": "pagination", className: cn('flex justify-center mx-auto w-full', className), ...props }));
9
+ }
10
+ function PaginationContent({ className, ...props }) {
11
+ return (_jsx("ul", { "data-slot": "pagination-content", className: cn('flex flex-row items-center gap-1', className), ...props }));
12
+ }
13
+ function PaginationItem({ className, ...props }) {
14
+ return _jsx("li", { "data-slot": "pagination-item", className: cn('', className), ...props });
15
+ }
16
+ function PaginationLink({ className, isActive, size = 'default', asChild = false, ...props }) {
17
+ const Comp = asChild ? Slot : 'a';
18
+ return (_jsx(Comp, { "aria-current": isActive ? 'page' : undefined, "data-slot": "pagination-link", "data-active": isActive, className: cn(paginationLinkBase, size === 'icon' && 'size-8 shrink-0', size === 'default' && 'h-8 min-w-8 px-2', isActive
19
+ ? 'border border-input bg-background text-foreground'
20
+ : 'border border-transparent text-foreground hover:bg-accent hover:text-accent-foreground', className), ...props }));
21
+ }
22
+ function PaginationPrevious({ className, ...props }) {
23
+ return (_jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn('pl-2', className), ...props, children: [_jsx(ChevronLeft, {}), _jsx("span", { children: "Prev" })] }));
24
+ }
25
+ function PaginationNext({ className, ...props }) {
26
+ return (_jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn('pr-2', className), ...props, children: [_jsx("span", { children: "Next" }), _jsx(ChevronRight, {})] }));
27
+ }
28
+ function PaginationEllipsis({ className, ...props }) {
29
+ return (_jsxs("span", { "aria-hidden": true, "data-slot": "pagination-ellipsis", className: cn('flex justify-center items-center size-8', className), ...props, children: [_jsx(MoreHorizontal, { className: "size-3.5" }), _jsx("span", { className: "sr-only", children: "More pages" })] }));
30
+ }
31
+ export { Pagination, PaginationContent, PaginationLink, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis, };
@@ -9,7 +9,7 @@ function PopoverTrigger({ ...props }) {
9
9
  return _jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
10
10
  }
11
11
  function PopoverContent({ className, align = 'center', sideOffset = 4, ...props }) {
12
- return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden', className), ...props }) }));
12
+ return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-sm border p-4 shadow-md outline-hidden', className), ...props }) }));
13
13
  }
14
14
  function PopoverAnchor({ ...props }) {
15
15
  return _jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Component that implements a basic search interface
3
3
  */
4
- export declare function SearchDialog({ debounceTime, charLimit, children, }: {
4
+ export declare function SearchDialog({ debounceTime, charLimit, children, onOpenChange, }: {
5
5
  debounceTime?: number;
6
6
  charLimit?: number;
7
7
  children: React.ReactNode;
8
+ onOpenChange?: (open: boolean) => void;
8
9
  }): import("react/jsx-runtime").JSX.Element;
9
10
  //# sourceMappingURL=search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/ui/search.tsx"],"names":[],"mappings":"AAieA;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAC3B,YAAkB,EAClB,SAAc,EACd,QAAQ,GACT,EAAE;IACD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAqFA"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/ui/search.tsx"],"names":[],"mappings":"AA8eA;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAC3B,YAAkB,EAClB,SAAc,EACd,QAAQ,EACR,YAAY,GACb,EAAE;IACD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC,2CA0FA"}
@@ -6,6 +6,7 @@ import { SPACE_OR_PUNCTUATION, rankResults } from '@myst-theme/search';
6
6
  import { useSearchFactory, useLinkProvider, withBaseurl, useBaseurl, useNavigateProvider, } from '@myst-theme/providers';
7
7
  import useSWR from 'swr';
8
8
  import { Search as SearchIcon } from 'lucide-react';
9
+ import { useAnalytics } from '../providers';
9
10
  /**
10
11
  * Loading bar component that shows at the top of the dialog
11
12
  */
@@ -199,20 +200,28 @@ function useSearch(shouldLoad = true) {
199
200
  function SearchForm({ debounceTime, searchResults, setSearchResults, searchInputID, searchListID, searchLabelID, selectedIndex, setSelectedIndex, closeSearch, loading, shouldLoad, }) {
200
201
  const [query, setQuery] = useState('');
201
202
  const { search: doSearch, enabled } = useSearch(shouldLoad);
203
+ const capture = useAnalytics();
202
204
  // Debounce user input
203
205
  useEffect(() => {
204
206
  const timeoutId = setTimeout(() => {
205
207
  if (query != undefined && !!doSearch) {
206
208
  doSearch(query).then((rawResults) => {
207
- setSearchResults(rawResults &&
209
+ const ranked = rawResults &&
208
210
  rankResults(rawResults)
209
211
  // Filter duplicates by URL
210
- .filter((result, index, array) => result.url !== array[index - 1]?.url));
212
+ .filter((result, index, array) => result.url !== array[index - 1]?.url);
213
+ setSearchResults(ranked);
214
+ if (query.length > 0) {
215
+ capture('search_performed', {
216
+ queryLength: query.length,
217
+ resultCount: ranked?.length ?? 0,
218
+ });
219
+ }
211
220
  });
212
221
  }
213
222
  }, debounceTime);
214
223
  return () => clearTimeout(timeoutId);
215
- }, [doSearch, query, debounceTime]);
224
+ }, [doSearch, query, debounceTime, capture]);
216
225
  // Handle user input
217
226
  const handleSearchChange = useCallback((event) => {
218
227
  setQuery(event.target.value);
@@ -234,6 +243,11 @@ function SearchForm({ debounceTime, searchResults, setSearchResults, searchInput
234
243
  event.preventDefault();
235
244
  const url = searchResults[selectedIndex]?.url;
236
245
  if (url) {
246
+ capture('search_result_selected', {
247
+ queryLength: query.length,
248
+ selectedIndex,
249
+ resultUrl: url,
250
+ });
237
251
  navigate(withBaseurl(url, baseurl));
238
252
  closeSearch?.();
239
253
  }
@@ -252,16 +266,20 @@ function SearchForm({ debounceTime, searchResults, setSearchResults, searchInput
252
266
  const onSubmit = useCallback((event) => {
253
267
  event.preventDefault();
254
268
  }, []);
255
- return (_jsxs(_Fragment, { children: [_jsx("form", { onSubmit: onSubmit, children: _jsxs("div", { className: "flex relative w-full h-10 flow-row", children: [_jsx("label", { id: searchListID, htmlFor: searchInputID, children: _jsx(SearchIcon, { className: "absolute text-gray-400 inset-y-0 start-0 h-10 w-10 p-2.5 aspect-square flex items-center pointer-events-none" }) }), _jsx("input", { autoComplete: "off", spellCheck: "false", disabled: !enabled, autoCapitalize: "false", className: cn('block flex-grow p-2 placeholder-gray-400 ps-10', 'border border-gray-300 dark:border-gray-600', 'bg-gray-50 rounded-sm dark:bg-gray-700', 'focus:ring-blue-500 dark:focus:ring-blue-500', 'focus:border-blue-500 dark:focus:border-blue-500', 'dark:placeholder-gray-400', { 'border-red-500': !enabled && !loading }), id: searchInputID, "aria-labelledby": searchLabelID, "aria-controls": searchListID, placeholder: "Search", type: "search", required: true, onChange: handleSearchChange, onKeyDown: handleSearchKeyPress })] }) }), !enabled && !loading && (_jsx("div", { className: "mx-2 mt-4 text-sm text-gray-500", children: "Search is not enabled for this site." }))] }));
269
+ return (_jsxs(_Fragment, { children: [_jsx("form", { onSubmit: onSubmit, children: _jsxs("div", { className: "flex relative w-full h-10 flow-row", children: [_jsx("label", { id: searchListID, htmlFor: searchInputID, children: _jsx(SearchIcon, { className: "absolute text-gray-400 inset-y-0 start-0 h-10 w-10 p-2.5 aspect-square flex items-center pointer-events-none" }) }), _jsx("input", { autoComplete: "off", spellCheck: "false", disabled: !enabled, autoCapitalize: "false", className: cn('block grow p-2 placeholder-gray-400 ps-10', 'border border-gray-300 dark:border-gray-600', 'bg-gray-50 rounded-sm dark:bg-gray-700', 'focus:ring-blue-500 dark:focus:ring-blue-500', 'focus:border-blue-500 dark:focus:border-blue-500', 'dark:placeholder-gray-400', { 'border-red-500': !enabled && !loading }), id: searchInputID, "aria-labelledby": searchLabelID, "aria-controls": searchListID, placeholder: "Search", type: "search", required: true, onChange: handleSearchChange, onKeyDown: handleSearchKeyPress })] }) }), !enabled && !loading && (_jsx("div", { className: "mx-2 mt-4 text-sm text-gray-500", children: "Search is not enabled for this site." }))] }));
256
270
  }
257
271
  /**
258
272
  * Component that implements a basic search interface
259
273
  */
260
- export function SearchDialog({ debounceTime = 500, charLimit = 64, children, }) {
274
+ export function SearchDialog({ debounceTime = 500, charLimit = 64, children, onOpenChange, }) {
261
275
  const [open, setOpen] = useState(false);
262
276
  const [searchResults, setSearchResults] = useState();
263
277
  const [selectedIndex, setSelectedIndex] = useState(0);
264
278
  const { loading } = useSearch(open);
279
+ const handleOpenChange = useCallback((next) => {
280
+ setOpen(next);
281
+ onOpenChange?.(next);
282
+ }, [onOpenChange]);
265
283
  // Clear search state on close
266
284
  useEffect(() => {
267
285
  if (!open) {
@@ -278,13 +296,11 @@ export function SearchDialog({ debounceTime = 500, charLimit = 64, children, })
278
296
  }, []);
279
297
  // Mount the document event handlers
280
298
  useEffect(() => {
281
- // attach the event listener
282
299
  document.addEventListener('keydown', handleDocumentKeyPress);
283
- // remove the event listener
284
300
  return () => {
285
301
  document.removeEventListener('keydown', handleDocumentKeyPress);
286
302
  };
287
303
  }, [handleDocumentKeyPress]);
288
304
  const triggerClose = useCallback(() => setOpen(false), [setOpen]);
289
- return (_jsxs(Dialog.Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(Dialog.DialogTrigger, { asChild: true, children: _jsx("div", { className: "cursor-pointer", children: children }) }), _jsxs(Dialog.DialogPortal, { children: [_jsx(Dialog.DialogOverlay, {}), _jsx(Dialog.DialogContent, { className: "fixed top-4 sm:top-[10vh] left-1/2 -translate-x-1/2 w-[90vw] max-w-screen-sm max-h-[calc(100vh-2rem)] sm:max-h-[70vh] overflow-hidden translate-y-0 p-0", showCloseButton: false, children: _jsxs("div", { className: "flex overflow-hidden relative flex-col gap-0 p-4", children: [_jsx(Dialog.DialogTitle, { className: "sr-only", children: "Search Website" }), _jsx(Dialog.DialogDescription, { className: "sr-only", children: "Search articles and their contents using fuzzy-search and prefix-matching" }), _jsx("div", { className: "flex-shrink-0", children: _jsx(SearchForm, { searchListID: "search-list", searchLabelID: "search-label", searchInputID: "search-input", debounceTime: debounceTime, searchResults: searchResults, setSearchResults: setSearchResults, selectedIndex: selectedIndex, setSelectedIndex: setSelectedIndex, closeSearch: triggerClose, loading: loading, shouldLoad: open }) }), searchResults && (_jsx("div", { className: "overflow-hidden flex-1", children: _jsx(SearchResults, { searchListID: "search-list", searchLabelID: "search-label", className: "overflow-y-auto h-full", searchResults: searchResults, selectedIndex: selectedIndex, onHoverSelect: setSelectedIndex, closeSearch: triggerClose, charLimit: charLimit }) }))] }) })] })] }));
305
+ return (_jsxs(Dialog.Dialog, { open: open, onOpenChange: handleOpenChange, children: [_jsx(Dialog.DialogTrigger, { asChild: true, children: _jsx("div", { className: "cursor-pointer", children: children }) }), _jsxs(Dialog.DialogPortal, { children: [_jsx(Dialog.DialogOverlay, {}), _jsx(Dialog.DialogContent, { className: "fixed top-4 sm:top-[10vh] left-1/2 -translate-x-1/2 w-[90vw] max-w-screen-sm max-h-[calc(100vh-2rem)] sm:max-h-[70vh] overflow-hidden translate-y-0 p-0", showCloseButton: false, children: _jsxs("div", { className: "flex overflow-hidden relative flex-col gap-0 p-4", children: [_jsx(Dialog.DialogTitle, { className: "sr-only", children: "Search Website" }), _jsx(Dialog.DialogDescription, { className: "sr-only", children: "Search articles and their contents using fuzzy-search and prefix-matching" }), _jsx("div", { className: "shrink-0", children: _jsx(SearchForm, { searchListID: "search-list", searchLabelID: "search-label", searchInputID: "search-input", debounceTime: debounceTime, searchResults: searchResults, setSearchResults: setSearchResults, selectedIndex: selectedIndex, setSelectedIndex: setSelectedIndex, closeSearch: triggerClose, loading: loading, shouldLoad: open }) }), searchResults && (_jsx("div", { className: "overflow-hidden flex-1", children: _jsx(SearchResults, { searchListID: "search-list", searchLabelID: "search-label", className: "overflow-y-auto h-full", searchResults: searchResults, selectedIndex: selectedIndex, onHoverSelect: setSelectedIndex, closeSearch: triggerClose, charLimit: charLimit }) }))] }) })] })] }));
290
306
  }
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import * as SelectPrimitive from '@radix-ui/react-select';
3
+ declare function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
4
+ declare function SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>): import("react/jsx-runtime").JSX.Element;
5
+ declare function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>): import("react/jsx-runtime").JSX.Element;
6
+ declare function SelectTrigger({ className, size, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
7
+ size?: 'sm' | 'default';
8
+ }): import("react/jsx-runtime").JSX.Element;
9
+ declare function SelectContent({ className, children, position, ...props }: React.ComponentProps<typeof SelectPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
10
+ declare function SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>): import("react/jsx-runtime").JSX.Element;
11
+ declare function SelectItem({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Item>): import("react/jsx-runtime").JSX.Element;
12
+ declare function SelectSeparator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Separator>): import("react/jsx-runtime").JSX.Element;
13
+ declare function SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>): import("react/jsx-runtime").JSX.Element;
14
+ declare function SelectScrollDownButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>): import("react/jsx-runtime").JSX.Element;
15
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, };
16
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/ui/select.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAK1D,iBAAS,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,2CAE9E;AAED,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,2CAEpF;AAED,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,2CAEpF;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,IAAgB,EAChB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG;IACxD,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;CACzB,2CAiBA;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,QAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,2CA4BtD;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,2CAQ/F;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,2CAkBnD;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,SAAS,CAAC,2CAQxD;AAED,iBAAS,oBAAoB,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,cAAc,CAAC,2CAU7D;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,gBAAgB,CAAC,2CAU/D;AAED,OAAO,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,WAAW,GACZ,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import * as SelectPrimitive from '@radix-ui/react-select';
4
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
5
+ import { cn } from '../../lib/utils';
6
+ function Select({ ...props }) {
7
+ return _jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
8
+ }
9
+ function SelectGroup({ ...props }) {
10
+ return _jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
11
+ }
12
+ function SelectValue({ ...props }) {
13
+ return _jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
14
+ }
15
+ function SelectTrigger({ className, size = 'default', children, ...props }) {
16
+ return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-stone-950 dark:hover:bg-stone-900 flex w-fit items-center justify-between gap-2 rounded-md border bg-white px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "opacity-50 size-4" }) })] }));
17
+ }
18
+ function SelectContent({ className, children, position = 'popper', ...props }) {
19
+ return (_jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { "data-slot": "select-content", className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md', position === 'popper' &&
20
+ 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', className), position: position, ...props, children: [_jsx(SelectScrollUpButton, {}), _jsx(SelectPrimitive.Viewport, { className: cn('p-1', position === 'popper' &&
21
+ 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1'), children: children }), _jsx(SelectScrollDownButton, {})] }) }));
22
+ }
23
+ function SelectLabel({ className, ...props }) {
24
+ return (_jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn('text-muted-foreground px-2 py-1.5 text-xs', className), ...props }));
25
+ }
26
+ function SelectItem({ className, children, ...props }) {
27
+ return (_jsxs(SelectPrimitive.Item, { "data-slot": "select-item", className: cn("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className), ...props, children: [_jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: _jsx(SelectPrimitive.ItemIndicator, { children: _jsx(CheckIcon, { className: "size-4" }) }) }), _jsx(SelectPrimitive.ItemText, { children: children })] }));
28
+ }
29
+ function SelectSeparator({ className, ...props }) {
30
+ return (_jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", className: cn('bg-border pointer-events-none -mx-1 my-1 h-px', className), ...props }));
31
+ }
32
+ function SelectScrollUpButton({ className, ...props }) {
33
+ return (_jsx(SelectPrimitive.ScrollUpButton, { "data-slot": "select-scroll-up-button", className: cn('flex cursor-default items-center justify-center py-1', className), ...props, children: _jsx(ChevronUpIcon, { className: "size-4" }) }));
34
+ }
35
+ function SelectScrollDownButton({ className, ...props }) {
36
+ return (_jsx(SelectPrimitive.ScrollDownButton, { "data-slot": "select-scroll-down-button", className: cn('flex cursor-default items-center justify-center py-1', className), ...props, children: _jsx(ChevronDownIcon, { className: "size-4" }) }));
37
+ }
38
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, };
@@ -3,6 +3,6 @@ import * as React from 'react';
3
3
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
4
4
  import { cn } from '../../lib/utils';
5
5
  function Separator({ className, orientation = 'horizontal', decorative = true, ...props }) {
6
- return (_jsx(SeparatorPrimitive.Root, { "data-slot": "separator", decorative: decorative, orientation: orientation, className: cn('bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px', className), ...props }));
6
+ return (_jsx(SeparatorPrimitive.Root, { "data-slot": "separator", decorative: decorative, orientation: orientation, className: cn('bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px dark:bg-white/60', className), ...props }));
7
7
  }
8
8
  export { Separator };
@@ -1,6 +1,5 @@
1
1
  import * as React from 'react';
2
- import { type VariantProps } from 'class-variance-authority';
3
- import { Button, Input, Separator, TooltipContent } from '.';
2
+ import { Button, Input, Separator } from '.';
4
3
  type SidebarContextProps = {
5
4
  state: 'expanded' | 'collapsed';
6
5
  open: boolean;
@@ -39,15 +38,6 @@ declare function SidebarGroupAction({ className, asChild, ...props }: React.Comp
39
38
  declare function SidebarGroupContent({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
40
39
  declare function SidebarMenu({ className, ...props }: React.ComponentProps<'ul'>): import("react/jsx-runtime").JSX.Element;
41
40
  declare function SidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>): import("react/jsx-runtime").JSX.Element;
42
- declare const sidebarMenuButtonVariants: (props?: ({
43
- variant?: "default" | "outline" | null | undefined;
44
- size?: "default" | "sm" | "lg" | null | undefined;
45
- } & import("class-variance-authority/types").ClassProp) | undefined) => string;
46
- declare function SidebarMenuButton({ asChild, isActive, variant, size, tooltip, className, ...props }: React.ComponentProps<'button'> & {
47
- asChild?: boolean;
48
- isActive?: boolean;
49
- tooltip?: string | React.ComponentProps<typeof TooltipContent>;
50
- } & VariantProps<typeof sidebarMenuButtonVariants>): import("react/jsx-runtime").JSX.Element;
51
41
  declare function SidebarMenuAction({ className, asChild, showOnHover, ...props }: React.ComponentProps<'button'> & {
52
42
  asChild?: boolean;
53
43
  showOnHover?: boolean;
@@ -63,5 +53,5 @@ declare function SidebarMenuSubButton({ asChild, size, isActive, className, ...p
63
53
  size?: 'sm' | 'md';
64
54
  isActive?: boolean;
65
55
  }): import("react/jsx-runtime").JSX.Element;
66
- export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar, };
56
+ export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar, };
67
57
  //# sourceMappingURL=sidebar.d.ts.map