@toolr/ui-design 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +63 -0
  2. package/components/content/info-panel-primitives.tsx +297 -0
  3. package/components/diagrams/diagram-utils.tsx +908 -0
  4. package/components/hooks/use-click-outside.ts +27 -0
  5. package/components/hooks/use-dropdown-max-height.ts +20 -0
  6. package/components/hooks/use-navigation-history.ts +94 -0
  7. package/components/lib/ai-tools.tsx +44 -0
  8. package/components/lib/cn.ts +6 -0
  9. package/components/lib/form-colors.ts +32 -0
  10. package/components/lib/theme-engine.ts +97 -0
  11. package/components/lib/toolr-brand.tsx +31 -0
  12. package/components/sections/ai-tools-paths/index.ts +37 -0
  13. package/components/sections/ai-tools-paths/tools-paths-panel.tsx +212 -0
  14. package/components/sections/ai-tools-paths/types.ts +111 -0
  15. package/components/sections/ai-tools-paths/use-tools-paths.ts +159 -0
  16. package/components/sections/captured-issues/captured-issues-panel.tsx +214 -0
  17. package/components/sections/captured-issues/index.ts +38 -0
  18. package/components/sections/captured-issues/types.ts +113 -0
  19. package/components/sections/captured-issues/use-captured-issues.ts +111 -0
  20. package/components/sections/golden-snapshots/file-diff-viewer.tsx +420 -0
  21. package/components/sections/golden-snapshots/golden-sync-panel.tsx +223 -0
  22. package/components/sections/golden-snapshots/index.ts +145 -0
  23. package/components/sections/golden-snapshots/snapshot-manager.tsx +200 -0
  24. package/components/sections/golden-snapshots/status-overview.tsx +305 -0
  25. package/components/sections/golden-snapshots/types.ts +288 -0
  26. package/components/sections/golden-snapshots/use-golden-sync.ts +477 -0
  27. package/components/sections/golden-snapshots/version-manager.tsx +186 -0
  28. package/components/sections/prompt-editor/file-type-tabbed-prompt-editor.tsx +210 -0
  29. package/components/sections/prompt-editor/index.ts +121 -0
  30. package/components/sections/prompt-editor/simulator-prompt-editor.tsx +276 -0
  31. package/components/sections/prompt-editor/tabbed-prompt-editor.tsx +514 -0
  32. package/components/sections/prompt-editor/types.ts +101 -0
  33. package/components/sections/prompt-editor/use-prompt-editor.ts +131 -0
  34. package/components/sections/report-bug/error-logger.ts +392 -0
  35. package/components/sections/report-bug/index.ts +59 -0
  36. package/components/sections/report-bug/issue-reporter-api.ts +83 -0
  37. package/components/sections/report-bug/report-bug-form.tsx +282 -0
  38. package/components/sections/report-bug/screenshot-uploader.tsx +228 -0
  39. package/components/sections/report-bug/use-report-bug.ts +170 -0
  40. package/components/sections/snapshot-browser/index.ts +53 -0
  41. package/components/sections/snapshot-browser/snapshot-browser-panel.tsx +147 -0
  42. package/components/sections/snapshot-browser/snapshot-tree.tsx +451 -0
  43. package/components/sections/snapshot-browser/types.ts +106 -0
  44. package/components/sections/snapshot-browser/use-snapshot-browser.ts +125 -0
  45. package/components/sections/snippets-editor/index.ts +31 -0
  46. package/components/sections/snippets-editor/snippets-editor.tsx +381 -0
  47. package/components/sections/snippets-editor/types.ts +48 -0
  48. package/components/sections/snippets-editor/use-snippets-editor.ts +217 -0
  49. package/components/ui/action-dialog.tsx +309 -0
  50. package/components/ui/ai-action-button.tsx +137 -0
  51. package/components/ui/ai-execution-action-buttons.tsx +106 -0
  52. package/components/ui/badge.tsx +67 -0
  53. package/components/ui/bottom-panel-header.tsx +240 -0
  54. package/components/ui/breadcrumb.tsx +168 -0
  55. package/components/ui/checkbox.tsx +102 -0
  56. package/components/ui/collapsible-section.tsx +100 -0
  57. package/components/ui/confirm-badge.tsx +71 -0
  58. package/components/ui/detail-section.tsx +67 -0
  59. package/components/ui/detail-view-wrapper.tsx +55 -0
  60. package/components/ui/editor-placeholder-card.tsx +197 -0
  61. package/components/ui/editor-toolbar.tsx +123 -0
  62. package/components/ui/execution-details-panel.tsx +93 -0
  63. package/components/ui/extension-list-card.tsx +105 -0
  64. package/components/ui/file-structure-section.tsx +373 -0
  65. package/components/ui/file-tree.tsx +171 -0
  66. package/components/ui/files-panel.tsx +251 -0
  67. package/components/ui/filter-dropdown.tsx +173 -0
  68. package/components/ui/form-actions.tsx +127 -0
  69. package/components/ui/frontmatter-form-header.tsx +80 -0
  70. package/components/ui/icon-button.tsx +388 -0
  71. package/components/ui/input.tsx +211 -0
  72. package/components/ui/label.tsx +159 -0
  73. package/components/ui/layout-tab-bar.tsx +289 -0
  74. package/components/ui/modal.tsx +194 -0
  75. package/components/ui/nav-card.tsx +81 -0
  76. package/components/ui/navigation-bar.tsx +285 -0
  77. package/components/ui/number-input.tsx +165 -0
  78. package/components/ui/registry-browser.tsx +261 -0
  79. package/components/ui/registry-card.tsx +710 -0
  80. package/components/ui/registry-detail.tsx +224 -0
  81. package/components/ui/resizable-textarea.tsx +290 -0
  82. package/components/ui/scope-badge.tsx +67 -0
  83. package/components/ui/segmented-toggle.tsx +133 -0
  84. package/components/ui/select.tsx +172 -0
  85. package/components/ui/selection-grid.tsx +313 -0
  86. package/components/ui/setting-row.tsx +97 -0
  87. package/components/ui/snapshot-card.tsx +107 -0
  88. package/components/ui/snippets-panel.tsx +161 -0
  89. package/components/ui/sort-dropdown.tsx +109 -0
  90. package/components/ui/status-card.tsx +96 -0
  91. package/components/ui/tab-bar.tsx +340 -0
  92. package/components/ui/toggle.tsx +142 -0
  93. package/components/ui/tooltip.tsx +326 -0
  94. package/dist/content.d.ts +110 -0
  95. package/dist/content.js +195 -0
  96. package/dist/diagrams.d.ts +371 -0
  97. package/dist/diagrams.js +702 -0
  98. package/dist/index.d.ts +2714 -0
  99. package/dist/index.js +11220 -0
  100. package/dist/preset.d.ts +24 -0
  101. package/dist/preset.js +17 -0
  102. package/dist/tokens/tokens/primitives.css +45 -0
  103. package/dist/tokens/tokens/semantic.css +46 -0
  104. package/dist/tokens/tokens/theme.css +11 -0
  105. package/dist/tokens/tokens/tokens.json +65 -0
  106. package/index.ts +123 -0
  107. package/package.json +63 -0
  108. package/tailwind-preset.ts +22 -0
  109. package/tokens/primitives.css +45 -0
  110. package/tokens/semantic.css +46 -0
  111. package/tokens/theme.css +11 -0
  112. package/tokens/tokens.json +65 -0
@@ -0,0 +1,326 @@
1
+ import { useState, useRef, useLayoutEffect, useEffect } from 'react'
2
+ import type { ReactNode } from 'react'
3
+ import { createPortal } from 'react-dom'
4
+
5
+ export interface TooltipContent {
6
+ title?: string
7
+ /** Description can be a string or React node for rich content with icons/colors */
8
+ description: string | ReactNode
9
+ extra?: string
10
+ }
11
+
12
+ export type TooltipPosition = 'top' | 'bottom' | 'left' | 'right' | 'auto'
13
+ export type TooltipAlign = 'start' | 'center' | 'end'
14
+ type ResolvedPosition = 'top' | 'bottom' | 'left' | 'right'
15
+
16
+ interface TooltipProps {
17
+ children: ReactNode
18
+ /** Tooltip content with required title and description */
19
+ content: TooltipContent
20
+ position?: TooltipPosition
21
+ align?: TooltipAlign
22
+ /** Allow multi-line content (disables whitespace-nowrap) */
23
+ multiline?: boolean
24
+ /** Maximum width for multiline tooltips (number for px, string for CSS value, default '80vw') */
25
+ maxWidth?: number | string
26
+ /** Maximum height for scrollable tooltips (only when interactive) */
27
+ maxHeight?: number
28
+ /** Allow hovering into the tooltip and scrolling its content */
29
+ interactive?: boolean
30
+ /** Trigger mode: 'hover' (default) or 'click' (toggle on click, dismiss on click-outside) */
31
+ trigger?: 'hover' | 'click'
32
+ /** Additional classes for the wrapper element (e.g., 'h-full' for flex containers) */
33
+ wrapperClassName?: string
34
+ }
35
+
36
+ const TOOLTIP_GAP = 8
37
+ const VIEWPORT_PADDING = 8
38
+ const AUTO_POSITION_THRESHOLD = 16
39
+
40
+ /** Resolve auto position based on available space */
41
+ function resolveAutoPosition(
42
+ triggerRect: DOMRect,
43
+ tooltipRect: DOMRect
44
+ ): ResolvedPosition {
45
+ const spaceAbove = triggerRect.top
46
+ const spaceBelow = window.innerHeight - triggerRect.bottom
47
+ const requiredSpace = tooltipRect.height + AUTO_POSITION_THRESHOLD
48
+
49
+ if (spaceAbove >= requiredSpace) return 'top'
50
+ if (spaceBelow >= requiredSpace) return 'bottom'
51
+ return 'top'
52
+ }
53
+
54
+ /** Calculate initial position based on trigger and resolved position */
55
+ function calculateBasePosition(
56
+ triggerRect: DOMRect,
57
+ resolvedPosition: ResolvedPosition,
58
+ align: TooltipAlign
59
+ ): { top: number; left: number } {
60
+ let top = 0
61
+ let left = 0
62
+
63
+ switch (resolvedPosition) {
64
+ case 'top':
65
+ top = triggerRect.top - TOOLTIP_GAP
66
+ left = align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right : triggerRect.left + triggerRect.width / 2
67
+ break
68
+ case 'bottom':
69
+ top = triggerRect.bottom + TOOLTIP_GAP
70
+ left = align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right : triggerRect.left + triggerRect.width / 2
71
+ break
72
+ case 'left':
73
+ top = triggerRect.top + triggerRect.height / 2
74
+ left = triggerRect.left - TOOLTIP_GAP
75
+ break
76
+ case 'right':
77
+ top = triggerRect.top + triggerRect.height / 2
78
+ left = triggerRect.right + TOOLTIP_GAP
79
+ break
80
+ }
81
+
82
+ return { top, left }
83
+ }
84
+
85
+ /** Adjust position based on tooltip dimensions */
86
+ function adjustForTooltipSize(
87
+ coords: { top: number; left: number },
88
+ tooltipRect: DOMRect,
89
+ resolvedPosition: ResolvedPosition,
90
+ align: TooltipAlign
91
+ ): { top: number; left: number } {
92
+ let { top, left } = coords
93
+
94
+ if (resolvedPosition === 'top') {
95
+ top -= tooltipRect.height
96
+ }
97
+
98
+ const isVertical = resolvedPosition === 'top' || resolvedPosition === 'bottom'
99
+ if (isVertical) {
100
+ if (align === 'center') {
101
+ left -= tooltipRect.width / 2
102
+ } else if (align === 'end') {
103
+ left -= tooltipRect.width
104
+ }
105
+ }
106
+
107
+ if (resolvedPosition === 'left') {
108
+ left -= tooltipRect.width
109
+ top -= tooltipRect.height / 2
110
+ }
111
+
112
+ if (resolvedPosition === 'right') {
113
+ top -= tooltipRect.height / 2
114
+ }
115
+
116
+ return { top, left }
117
+ }
118
+
119
+ /** Clamp position to viewport bounds */
120
+ function clampToViewport(
121
+ coords: { top: number; left: number },
122
+ tooltipRect: DOMRect
123
+ ): { top: number; left: number } {
124
+ let { top, left } = coords
125
+
126
+ if (left < VIEWPORT_PADDING) left = VIEWPORT_PADDING
127
+ if (left + tooltipRect.width > window.innerWidth - VIEWPORT_PADDING) {
128
+ left = window.innerWidth - tooltipRect.width - VIEWPORT_PADDING
129
+ }
130
+ if (top < VIEWPORT_PADDING) top = VIEWPORT_PADDING
131
+ if (top + tooltipRect.height > window.innerHeight - VIEWPORT_PADDING) {
132
+ top = window.innerHeight - tooltipRect.height - VIEWPORT_PADDING
133
+ }
134
+
135
+ return { top, left }
136
+ }
137
+
138
+ const ARROW_BASE_CLASSES = 'absolute w-3 h-3 bg-neutral-800 border-neutral-600 rotate-45'
139
+
140
+ function getAlignmentClass(align: TooltipAlign): string {
141
+ if (align === 'start') return 'left-2'
142
+ if (align === 'end') return 'right-2'
143
+ return 'left-1/2 -translate-x-1/2'
144
+ }
145
+
146
+ /** Get CSS classes for the tooltip arrow based on position and alignment */
147
+ function getArrowClasses(pos: ResolvedPosition, align: TooltipAlign): string {
148
+ switch (pos) {
149
+ case 'top':
150
+ return `${ARROW_BASE_CLASSES} -bottom-1.5 border-r border-b ${getAlignmentClass(align)}`
151
+ case 'bottom':
152
+ return `${ARROW_BASE_CLASSES} -top-1.5 border-l border-t ${getAlignmentClass(align)}`
153
+ case 'left':
154
+ return `${ARROW_BASE_CLASSES} -right-1.5 border-r border-t top-1/2 -translate-y-1/2`
155
+ case 'right':
156
+ return `${ARROW_BASE_CLASSES} -left-1.5 border-l border-b top-1/2 -translate-y-1/2`
157
+ default:
158
+ return ARROW_BASE_CLASSES
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Portal-based tooltip that renders at document body level.
164
+ * This ensures tooltips always appear above all other elements,
165
+ * regardless of parent overflow or z-index settings.
166
+ */
167
+ export function Tooltip({
168
+ children,
169
+ content,
170
+ position = 'top',
171
+ align = 'start',
172
+ multiline = false,
173
+ maxWidth,
174
+ maxHeight,
175
+ trigger = 'hover',
176
+ interactive = false,
177
+ wrapperClassName = '',
178
+ }: TooltipProps) {
179
+ const [isVisible, setIsVisible] = useState(false)
180
+ const [coords, setCoords] = useState({ top: 0, left: 0 })
181
+ const [actualPosition, setActualPosition] = useState<ResolvedPosition>(position === 'auto' ? 'top' : position)
182
+ const triggerRef = useRef<HTMLDivElement>(null)
183
+ const tooltipRef = useRef<HTMLDivElement>(null)
184
+ const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
185
+
186
+ const show = () => {
187
+ if (hideTimeoutRef.current) {
188
+ clearTimeout(hideTimeoutRef.current)
189
+ hideTimeoutRef.current = null
190
+ }
191
+ setIsVisible(true)
192
+ }
193
+
194
+ const hide = () => {
195
+ if (interactive) {
196
+ // Small delay so the user can move from trigger to tooltip
197
+ hideTimeoutRef.current = setTimeout(() => setIsVisible(false), 150)
198
+ } else {
199
+ setIsVisible(false)
200
+ }
201
+ }
202
+
203
+ // Click-outside dismissal for click trigger mode
204
+ useEffect(() => {
205
+ if (trigger !== 'click' || !isVisible) return
206
+ const handleClickOutside = (e: MouseEvent) => {
207
+ if (
208
+ triggerRef.current && !triggerRef.current.contains(e.target as Node) &&
209
+ tooltipRef.current && !tooltipRef.current.contains(e.target as Node)
210
+ ) {
211
+ setIsVisible(false)
212
+ }
213
+ }
214
+ document.addEventListener('mousedown', handleClickOutside)
215
+ return () => document.removeEventListener('mousedown', handleClickOutside)
216
+ }, [trigger, isVisible])
217
+
218
+ const updatePosition = () => {
219
+ if (!triggerRef.current) return
220
+ const triggerRect = triggerRef.current.getBoundingClientRect()
221
+ const tooltipEl = tooltipRef.current
222
+
223
+ let resolvedPosition: ResolvedPosition = position === 'auto' ? 'top' : position
224
+
225
+ if (position === 'auto' && tooltipEl) {
226
+ const tooltipRect = tooltipEl.getBoundingClientRect()
227
+ resolvedPosition = resolveAutoPosition(triggerRect, tooltipRect)
228
+ setActualPosition(resolvedPosition)
229
+ }
230
+
231
+ let newCoords = calculateBasePosition(triggerRect, resolvedPosition, align)
232
+
233
+ if (tooltipEl) {
234
+ const tooltipRect = tooltipEl.getBoundingClientRect()
235
+ newCoords = adjustForTooltipSize(newCoords, tooltipRect, resolvedPosition, align)
236
+ newCoords = clampToViewport(newCoords, tooltipRect)
237
+ }
238
+
239
+ setCoords(newCoords)
240
+ }
241
+
242
+ useLayoutEffect(() => {
243
+ if (!isVisible) return
244
+ updatePosition()
245
+ }, [isVisible, position, align])
246
+
247
+ // Reposition on scroll for click-triggered tooltips so they follow the trigger
248
+ useEffect(() => {
249
+ if (trigger !== 'click' || !isVisible) return
250
+ const handleScroll = () => updatePosition()
251
+ window.addEventListener('scroll', handleScroll, true)
252
+ return () => window.removeEventListener('scroll', handleScroll, true)
253
+ }, [trigger, isVisible, position, align])
254
+
255
+ const resolvedPos = position === 'auto' ? actualPosition : position
256
+ const arrowClasses = getArrowClasses(resolvedPos, align)
257
+
258
+ const tooltipContent = (
259
+ <div
260
+ ref={tooltipRef}
261
+ className={`fixed px-3 py-1.5 bg-neutral-800 border border-neutral-600 rounded-lg shadow-xl z-[9999] ${interactive || trigger === 'click' ? '' : 'pointer-events-none'} ${multiline ? 'whitespace-pre-line' : 'whitespace-nowrap'}`}
262
+ style={{
263
+ top: coords.top,
264
+ left: coords.left,
265
+ opacity: isVisible ? 1 : 0,
266
+ visibility: isVisible ? 'visible' : 'hidden',
267
+ transition: 'opacity 150ms, visibility 150ms',
268
+ ...(multiline ? { maxWidth: maxWidth ?? '80vw' } : {}),
269
+ ...(maxHeight ? { maxHeight, overflowY: 'auto' as const } : {}),
270
+ }}
271
+ onMouseEnter={interactive && trigger !== 'click' ? show : undefined}
272
+ onMouseLeave={interactive && trigger !== 'click' ? hide : undefined}
273
+ >
274
+ {content.title && <p className="text-sm text-neutral-200 font-medium">{content.title}</p>}
275
+ <div className={`text-xs text-neutral-400 ${content.title ? 'mt-0.5' : ''}`}>{content.description}</div>
276
+ {content.extra && <p className="text-xs text-orange-400/70 mt-0.5">{content.extra}</p>}
277
+ <div className={arrowClasses} />
278
+ </div>
279
+ )
280
+
281
+ return (
282
+ <>
283
+ <div
284
+ ref={triggerRef}
285
+ onMouseEnter={trigger === 'hover' ? show : undefined}
286
+ onMouseLeave={trigger === 'hover' ? hide : undefined}
287
+ onMouseDown={trigger === 'hover' ? () => setIsVisible(false) : undefined}
288
+ onClick={trigger === 'click' ? () => setIsVisible((v) => !v) : undefined}
289
+ className={wrapperClassName || 'inline-flex'}
290
+ >
291
+ {children}
292
+ </div>
293
+ {createPortal(tooltipContent, document.body)}
294
+ </>
295
+ )
296
+ }
297
+
298
+ /**
299
+ * Simple tooltip wrapper for icon buttons.
300
+ * Provides consistent styling for action button tooltips.
301
+ */
302
+ export function TooltipButton({
303
+ children,
304
+ content,
305
+ onClick,
306
+ className,
307
+ disabled,
308
+ }: {
309
+ children: ReactNode
310
+ content: TooltipContent
311
+ onClick?: () => void
312
+ className?: string
313
+ disabled?: boolean
314
+ }) {
315
+ return (
316
+ <Tooltip content={content} position="top" align="start">
317
+ <button
318
+ onClick={onClick}
319
+ disabled={disabled}
320
+ className={className}
321
+ >
322
+ {children}
323
+ </button>
324
+ </Tooltip>
325
+ )
326
+ }
@@ -0,0 +1,110 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare function P({ children }: {
5
+ children: ReactNode;
6
+ }): react_jsx_runtime.JSX.Element;
7
+ declare function SectionHeader({ color, children }: {
8
+ color?: string;
9
+ children: ReactNode;
10
+ }): react_jsx_runtime.JSX.Element;
11
+ declare function DL({ children }: {
12
+ children: ReactNode;
13
+ }): react_jsx_runtime.JSX.Element;
14
+ declare function DLRow({ term, children, even }: {
15
+ term: ReactNode;
16
+ children: ReactNode;
17
+ even?: boolean;
18
+ }): react_jsx_runtime.JSX.Element;
19
+ declare function UL({ children }: {
20
+ children: ReactNode;
21
+ }): react_jsx_runtime.JSX.Element;
22
+ declare function LI({ color, children }: {
23
+ color: string;
24
+ children: ReactNode;
25
+ }): react_jsx_runtime.JSX.Element;
26
+ declare function OL({ children }: {
27
+ children: ReactNode;
28
+ }): react_jsx_runtime.JSX.Element;
29
+ declare function OLI({ n, color, children }: {
30
+ n: number;
31
+ color: string;
32
+ children: ReactNode;
33
+ }): react_jsx_runtime.JSX.Element;
34
+ declare function getCalloutColors(color: string): {
35
+ borderL: string;
36
+ borderY: string;
37
+ bg: string;
38
+ text: string;
39
+ codeText: string;
40
+ dimText: string;
41
+ };
42
+ declare function Callout({ color, children }: {
43
+ color: string;
44
+ children: ReactNode;
45
+ }): react_jsx_runtime.JSX.Element;
46
+ declare function CalloutCode({ color, children }: {
47
+ color: string;
48
+ children: ReactNode;
49
+ }): react_jsx_runtime.JSX.Element;
50
+ declare function CalloutDim({ children }: {
51
+ children: ReactNode;
52
+ }): react_jsx_runtime.JSX.Element;
53
+ declare function CodeBlock({ children }: {
54
+ children: ReactNode;
55
+ }): react_jsx_runtime.JSX.Element;
56
+ declare function CK({ color, children }: {
57
+ color?: string;
58
+ children: ReactNode;
59
+ }): react_jsx_runtime.JSX.Element;
60
+ declare function ExternalLink({ href, children }: {
61
+ href: string;
62
+ children: ReactNode;
63
+ }): react_jsx_runtime.JSX.Element;
64
+ declare function LocationList({ children }: {
65
+ children: ReactNode;
66
+ }): react_jsx_runtime.JSX.Element;
67
+ declare function LocationItem({ color, label, children, even, }: {
68
+ color: string;
69
+ label: string;
70
+ children: ReactNode;
71
+ even?: boolean;
72
+ }): react_jsx_runtime.JSX.Element;
73
+ declare function TitledLI({ color, title, children }: {
74
+ color: string;
75
+ title: string;
76
+ children: ReactNode;
77
+ }): react_jsx_runtime.JSX.Element;
78
+ declare function CalloutDialog({ color, lines }: {
79
+ color: string;
80
+ lines: {
81
+ speaker: string;
82
+ text: string;
83
+ }[];
84
+ }): react_jsx_runtime.JSX.Element;
85
+ declare function TagGrid({ color, tags }: {
86
+ color: string;
87
+ tags: string[];
88
+ }): react_jsx_runtime.JSX.Element;
89
+ declare function StatusBadge({ value, badgeColor, label, children, even }: {
90
+ value: string;
91
+ badgeColor: string;
92
+ label: string;
93
+ children: ReactNode;
94
+ even?: boolean;
95
+ }): react_jsx_runtime.JSX.Element;
96
+ declare function BulletGridRow({ color, term, children, even }: {
97
+ color: string;
98
+ term: string;
99
+ children: ReactNode;
100
+ even?: boolean;
101
+ }): react_jsx_runtime.JSX.Element;
102
+ declare function NumberGridRow({ color, n, term, children, even }: {
103
+ color: string;
104
+ n: number;
105
+ term: string;
106
+ children: ReactNode;
107
+ even?: boolean;
108
+ }): react_jsx_runtime.JSX.Element;
109
+
110
+ export { BulletGridRow, CK, Callout, CalloutCode, CalloutDialog, CalloutDim, CodeBlock, DL, DLRow, ExternalLink, LI, LocationItem, LocationList, NumberGridRow, OL, OLI, P, SectionHeader, StatusBadge, TagGrid, TitledLI, UL, getCalloutColors };
@@ -0,0 +1,195 @@
1
+ // components/content/info-panel-primitives.tsx
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ function P({ children }) {
4
+ return /* @__PURE__ */ jsx("p", { className: "text-sm text-neutral-400 leading-relaxed mb-5", children });
5
+ }
6
+ function SectionHeader({ color, children }) {
7
+ const textColor = color ? `text-${color}-500/70` : "text-neutral-500";
8
+ return /* @__PURE__ */ jsx("p", { className: `${textColor} text-xs uppercase font-semibold pb-0.5 border-b border-neutral-700/50 mb-2.5`, style: { letterSpacing: "0.8px" }, children });
9
+ }
10
+ function DL({ children }) {
11
+ return /* @__PURE__ */ jsx("div", { className: "mb-5", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[auto_1fr] gap-x-4", children }) });
12
+ }
13
+ function DLRow({ term, children, even }) {
14
+ const bg = even ? "bg-white/[0.015]" : "";
15
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
16
+ /* @__PURE__ */ jsx("div", { className: `py-2 border-b border-neutral-800/60 ${bg} font-semibold text-sm whitespace-nowrap`, children: term }),
17
+ /* @__PURE__ */ jsx("div", { className: `py-2 border-b border-neutral-800/60 ${bg} text-sm text-neutral-400`, children })
18
+ ] });
19
+ }
20
+ function UL({ children }) {
21
+ return /* @__PURE__ */ jsx("ul", { className: "text-sm text-neutral-400 space-y-2 mb-5", children });
22
+ }
23
+ function LI({ color, children }) {
24
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2", children: [
25
+ /* @__PURE__ */ jsx("span", { className: `text-${color}-400 shrink-0`, style: { marginTop: "3px", fontSize: "18px", lineHeight: "14px" }, children: "\u2022" }),
26
+ /* @__PURE__ */ jsx("span", { children })
27
+ ] });
28
+ }
29
+ function OL({ children }) {
30
+ return /* @__PURE__ */ jsx("div", { className: "space-y-2 mb-5", children });
31
+ }
32
+ function OLI({ n, color, children }) {
33
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2.5 text-sm", children: [
34
+ /* @__PURE__ */ jsxs("span", { className: `text-${color}-400 shrink-0 w-4 text-right font-bold`, children: [
35
+ n,
36
+ "."
37
+ ] }),
38
+ /* @__PURE__ */ jsx("span", { className: "text-neutral-400", children })
39
+ ] });
40
+ }
41
+ var CALLOUT_COLORS = {
42
+ amber: { borderL: "border-amber-500/40", borderY: "border-y-amber-500/15", bg: "bg-amber-500/5", text: "text-amber-400", codeText: "text-amber-300/80", dimText: "text-amber-400/60" },
43
+ blue: { borderL: "border-blue-500/40", borderY: "border-y-blue-500/15", bg: "bg-blue-500/5", text: "text-blue-400", codeText: "text-blue-300/80", dimText: "text-blue-400/60" },
44
+ cyan: { borderL: "border-cyan-500/40", borderY: "border-y-cyan-500/15", bg: "bg-cyan-500/5", text: "text-cyan-400", codeText: "text-cyan-300/80", dimText: "text-cyan-400/60" },
45
+ emerald: { borderL: "border-emerald-500/40", borderY: "border-y-emerald-500/15", bg: "bg-emerald-500/5", text: "text-emerald-400", codeText: "text-emerald-300/80", dimText: "text-emerald-400/60" },
46
+ fuchsia: { borderL: "border-fuchsia-500/40", borderY: "border-y-fuchsia-500/15", bg: "bg-fuchsia-500/5", text: "text-fuchsia-400", codeText: "text-fuchsia-300/80", dimText: "text-fuchsia-400/60" },
47
+ green: { borderL: "border-green-500/40", borderY: "border-y-green-500/15", bg: "bg-green-500/5", text: "text-green-400", codeText: "text-green-300/80", dimText: "text-green-400/60" },
48
+ indigo: { borderL: "border-indigo-500/40", borderY: "border-y-indigo-500/15", bg: "bg-indigo-500/5", text: "text-indigo-400", codeText: "text-indigo-300/80", dimText: "text-indigo-400/60" },
49
+ lime: { borderL: "border-lime-500/40", borderY: "border-y-lime-500/15", bg: "bg-lime-500/5", text: "text-lime-400", codeText: "text-lime-300/80", dimText: "text-lime-400/60" },
50
+ orange: { borderL: "border-orange-500/40", borderY: "border-y-orange-500/15", bg: "bg-orange-500/5", text: "text-orange-400", codeText: "text-orange-300/80", dimText: "text-orange-400/60" },
51
+ pink: { borderL: "border-pink-500/40", borderY: "border-y-pink-500/15", bg: "bg-pink-500/5", text: "text-pink-400", codeText: "text-pink-300/80", dimText: "text-pink-400/60" },
52
+ purple: { borderL: "border-purple-500/40", borderY: "border-y-purple-500/15", bg: "bg-purple-500/5", text: "text-purple-400", codeText: "text-purple-300/80", dimText: "text-purple-400/60" },
53
+ red: { borderL: "border-red-500/40", borderY: "border-y-red-500/15", bg: "bg-red-500/5", text: "text-red-400", codeText: "text-red-300/80", dimText: "text-red-400/60" },
54
+ rose: { borderL: "border-rose-500/40", borderY: "border-y-rose-500/15", bg: "bg-rose-500/5", text: "text-rose-400", codeText: "text-rose-300/80", dimText: "text-rose-400/60" },
55
+ sky: { borderL: "border-sky-500/40", borderY: "border-y-sky-500/15", bg: "bg-sky-500/5", text: "text-sky-400", codeText: "text-sky-300/80", dimText: "text-sky-400/60" },
56
+ teal: { borderL: "border-teal-500/40", borderY: "border-y-teal-500/15", bg: "bg-teal-500/5", text: "text-teal-400", codeText: "text-teal-300/80", dimText: "text-teal-400/60" },
57
+ violet: { borderL: "border-violet-500/40", borderY: "border-y-violet-500/15", bg: "bg-violet-500/5", text: "text-violet-400", codeText: "text-violet-300/80", dimText: "text-violet-400/60" }
58
+ };
59
+ function getCalloutColors(color) {
60
+ return CALLOUT_COLORS[color] ?? CALLOUT_COLORS.blue;
61
+ }
62
+ function Callout({ color, children }) {
63
+ const c = CALLOUT_COLORS[color] ?? CALLOUT_COLORS.blue;
64
+ return /* @__PURE__ */ jsx("div", { className: `border-l-4 ${c.borderL} border-y ${c.borderY} ${c.bg} px-3 py-2.5 rounded-r mb-5 text-sm text-neutral-400`, children });
65
+ }
66
+ function CalloutCode({ color, children }) {
67
+ const c = CALLOUT_COLORS[color] ?? CALLOUT_COLORS.blue;
68
+ return /* @__PURE__ */ jsx("code", { className: `block bg-neutral-800/80 px-2 py-1 rounded mt-1.5 text-[13px] ${c.codeText}`, children });
69
+ }
70
+ function CalloutDim({ children }) {
71
+ return /* @__PURE__ */ jsx("p", { className: "text-neutral-500 mt-1.5", children });
72
+ }
73
+ function CodeBlock({ children }) {
74
+ return /* @__PURE__ */ jsx("div", { className: "bg-neutral-900/60 rounded-md p-3 font-mono text-xs text-neutral-400 mb-5 whitespace-pre overflow-x-auto leading-normal", children });
75
+ }
76
+ function CK({ color, children }) {
77
+ const textColor = color ? `text-${color}-400` : "";
78
+ return /* @__PURE__ */ jsx("code", { className: `bg-neutral-800/80 px-1.5 py-px rounded text-[0.9em] ${textColor}`, children });
79
+ }
80
+ function ExternalLink({ href, children }) {
81
+ return /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", className: "underline cursor-pointer", children });
82
+ }
83
+ function LocationList({ children }) {
84
+ return /* @__PURE__ */ jsx("div", { className: "mb-5", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[auto_1fr] gap-x-4", children }) });
85
+ }
86
+ function LocationItem({
87
+ color,
88
+ label,
89
+ children,
90
+ even
91
+ }) {
92
+ const bg = even ? "bg-white/[0.015]" : "";
93
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
94
+ /* @__PURE__ */ jsxs("div", { className: `py-2 border-b border-neutral-800/60 ${bg} flex items-center gap-1.5`, children: [
95
+ /* @__PURE__ */ jsx(
96
+ "span",
97
+ {
98
+ className: `w-2 h-2 rounded-full bg-${color}-500/50 border border-${color}-500 shrink-0`
99
+ }
100
+ ),
101
+ /* @__PURE__ */ jsx("span", { className: `text-${color}-400 text-sm font-semibold`, children: label })
102
+ ] }),
103
+ /* @__PURE__ */ jsx("div", { className: `py-2 border-b border-neutral-800/60 ${bg} text-sm text-neutral-400`, children })
104
+ ] });
105
+ }
106
+ function TitledLI({ color, title, children }) {
107
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2 text-sm text-neutral-400", children: [
108
+ /* @__PURE__ */ jsx("span", { className: `text-${color}-400 shrink-0`, style: { marginTop: "3px", fontSize: "18px", lineHeight: "14px" }, children: "\u2022" }),
109
+ /* @__PURE__ */ jsxs("span", { children: [
110
+ /* @__PURE__ */ jsx("span", { className: `text-${color}-300 font-semibold`, children: title }),
111
+ " ",
112
+ "\u2014 ",
113
+ children
114
+ ] })
115
+ ] });
116
+ }
117
+ function CalloutDialog({ color, lines }) {
118
+ return /* @__PURE__ */ jsx("div", { className: "bg-neutral-800/80 rounded px-2 py-1 mt-1.5 flex flex-col gap-0.5 text-[13px]", children: lines.map((line, idx) => /* @__PURE__ */ jsxs("div", { children: [
119
+ /* @__PURE__ */ jsxs("span", { className: `text-${color}-300 font-semibold mr-1`, children: [
120
+ line.speaker,
121
+ ":"
122
+ ] }),
123
+ /* @__PURE__ */ jsx("span", { className: "text-neutral-400", children: line.text })
124
+ ] }, idx)) });
125
+ }
126
+ function TagGrid({ color, tags }) {
127
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5 mb-5", children: tags.map((tag) => /* @__PURE__ */ jsx(CK, { color, children: tag }, tag)) });
128
+ }
129
+ function StatusBadge({ value, badgeColor, label, children, even }) {
130
+ return /* @__PURE__ */ jsx(
131
+ DLRow,
132
+ {
133
+ term: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
134
+ /* @__PURE__ */ jsx("span", { className: `inline-flex items-center justify-center w-5 h-5 rounded-full bg-${badgeColor}-500/20 text-${badgeColor}-400 text-[11px] font-bold shrink-0`, children: value }),
135
+ /* @__PURE__ */ jsx("span", { className: `text-${badgeColor}-400 font-semibold`, children: label })
136
+ ] }),
137
+ even,
138
+ children
139
+ }
140
+ );
141
+ }
142
+ function BulletGridRow({ color, term, children, even }) {
143
+ return /* @__PURE__ */ jsx(
144
+ DLRow,
145
+ {
146
+ term: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
147
+ /* @__PURE__ */ jsx("span", { className: `text-${color}-400`, style: { fontSize: "18px", lineHeight: "14px" }, children: "\u2022" }),
148
+ /* @__PURE__ */ jsx("span", { className: `text-${color}-400 font-semibold`, children: term })
149
+ ] }),
150
+ even,
151
+ children
152
+ }
153
+ );
154
+ }
155
+ function NumberGridRow({ color, n, term, children, even }) {
156
+ return /* @__PURE__ */ jsx(
157
+ DLRow,
158
+ {
159
+ term: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
160
+ /* @__PURE__ */ jsxs("span", { className: `text-${color}-400 font-bold w-4 text-right shrink-0`, children: [
161
+ n,
162
+ "."
163
+ ] }),
164
+ /* @__PURE__ */ jsx("span", { className: `text-${color}-400 font-semibold`, children: term })
165
+ ] }),
166
+ even,
167
+ children
168
+ }
169
+ );
170
+ }
171
+ export {
172
+ BulletGridRow,
173
+ CK,
174
+ Callout,
175
+ CalloutCode,
176
+ CalloutDialog,
177
+ CalloutDim,
178
+ CodeBlock,
179
+ DL,
180
+ DLRow,
181
+ ExternalLink,
182
+ LI,
183
+ LocationItem,
184
+ LocationList,
185
+ NumberGridRow,
186
+ OL,
187
+ OLI,
188
+ P,
189
+ SectionHeader,
190
+ StatusBadge,
191
+ TagGrid,
192
+ TitledLI,
193
+ UL,
194
+ getCalloutColors
195
+ };