@harborclient/sdk 0.4.6 → 0.6.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 (178) hide show
  1. package/dist/components/AsyncListState/index.d.ts +85 -0
  2. package/dist/components/AsyncListState/index.d.ts.map +1 -0
  3. package/dist/components/AsyncListState/index.js +51 -0
  4. package/dist/components/BackButton/index.d.ts +32 -0
  5. package/dist/components/BackButton/index.d.ts.map +1 -0
  6. package/dist/components/BackButton/index.js +19 -0
  7. package/dist/components/Badge/index.d.ts +29 -0
  8. package/dist/components/Badge/index.d.ts.map +1 -0
  9. package/dist/components/Badge/index.js +32 -0
  10. package/dist/components/BusyIndicator/index.d.ts +16 -0
  11. package/dist/components/BusyIndicator/index.d.ts.map +1 -0
  12. package/dist/components/BusyIndicator/index.js +78 -0
  13. package/dist/components/Button/index.d.ts +29 -0
  14. package/dist/components/Button/index.d.ts.map +1 -0
  15. package/dist/components/Button/index.js +25 -0
  16. package/dist/components/CodeEditor/config.d.ts +51 -0
  17. package/dist/components/CodeEditor/config.d.ts.map +1 -0
  18. package/dist/components/CodeEditor/config.js +64 -0
  19. package/dist/components/CodeEditor/index.d.ts +77 -0
  20. package/dist/components/CodeEditor/index.d.ts.map +1 -0
  21. package/dist/components/CodeEditor/index.js +319 -0
  22. package/dist/components/CodeEditor/themes.d.ts +19 -0
  23. package/dist/components/CodeEditor/themes.d.ts.map +1 -0
  24. package/dist/components/CodeEditor/themes.js +37 -0
  25. package/dist/components/EmptyState/index.d.ts +26 -0
  26. package/dist/components/EmptyState/index.d.ts.map +1 -0
  27. package/dist/components/EmptyState/index.js +25 -0
  28. package/dist/components/FaIcon/index.d.ts +22 -0
  29. package/dist/components/FaIcon/index.d.ts.map +1 -0
  30. package/dist/components/FaIcon/index.js +13 -0
  31. package/dist/components/FieldError/index.d.ts +39 -0
  32. package/dist/components/FieldError/index.d.ts.map +1 -0
  33. package/dist/components/FieldError/index.js +34 -0
  34. package/dist/components/FooterButton/index.d.ts +30 -0
  35. package/dist/components/FooterButton/index.d.ts.map +1 -0
  36. package/dist/components/FooterButton/index.js +19 -0
  37. package/dist/components/FooterIcon/index.d.ts +32 -0
  38. package/dist/components/FooterIcon/index.d.ts.map +1 -0
  39. package/dist/components/FooterIcon/index.js +21 -0
  40. package/dist/components/FormDataEditor/index.d.ts +31 -0
  41. package/dist/components/FormDataEditor/index.d.ts.map +1 -0
  42. package/dist/components/FormDataEditor/index.js +109 -0
  43. package/dist/components/FormGroup/index.d.ts +75 -0
  44. package/dist/components/FormGroup/index.d.ts.map +1 -0
  45. package/dist/components/FormGroup/index.js +95 -0
  46. package/dist/components/KeyValueEditor/index.d.ts +35 -0
  47. package/dist/components/KeyValueEditor/index.d.ts.map +1 -0
  48. package/dist/components/KeyValueEditor/index.js +40 -0
  49. package/dist/components/MethodSelect/index.d.ts +20 -0
  50. package/dist/components/MethodSelect/index.d.ts.map +1 -0
  51. package/dist/components/MethodSelect/index.js +9 -0
  52. package/dist/components/Modal/ModalFooter.d.ts +25 -0
  53. package/dist/components/Modal/ModalFooter.d.ts.map +1 -0
  54. package/dist/components/Modal/ModalFooter.js +13 -0
  55. package/dist/components/Modal/ModalFormLayout.d.ts +31 -0
  56. package/dist/components/Modal/ModalFormLayout.d.ts.map +1 -0
  57. package/dist/components/Modal/ModalFormLayout.js +14 -0
  58. package/dist/components/Modal/ModalHeader.d.ts +34 -0
  59. package/dist/components/Modal/ModalHeader.d.ts.map +1 -0
  60. package/dist/components/Modal/ModalHeader.js +11 -0
  61. package/dist/components/Modal/index.d.ts +59 -0
  62. package/dist/components/Modal/index.d.ts.map +1 -0
  63. package/dist/components/Modal/index.js +37 -0
  64. package/dist/components/OverlayCloseButton/index.d.ts +25 -0
  65. package/dist/components/OverlayCloseButton/index.d.ts.map +1 -0
  66. package/dist/components/OverlayCloseButton/index.js +16 -0
  67. package/dist/components/OverlayPage/index.d.ts +40 -0
  68. package/dist/components/OverlayPage/index.d.ts.map +1 -0
  69. package/dist/components/OverlayPage/index.js +18 -0
  70. package/dist/components/PageHeader/index.d.ts +31 -0
  71. package/dist/components/PageHeader/index.d.ts.map +1 -0
  72. package/dist/components/PageHeader/index.js +12 -0
  73. package/dist/components/PanelCloseButton/index.d.ts +30 -0
  74. package/dist/components/PanelCloseButton/index.d.ts.map +1 -0
  75. package/dist/components/PanelCloseButton/index.js +17 -0
  76. package/dist/components/Resizable/Resizable.d.ts +48 -0
  77. package/dist/components/Resizable/Resizable.d.ts.map +1 -0
  78. package/dist/components/Resizable/Resizable.js +32 -0
  79. package/dist/components/Resizable/ResizeHandle.d.ts +41 -0
  80. package/dist/components/Resizable/ResizeHandle.d.ts.map +1 -0
  81. package/dist/components/Resizable/ResizeHandle.js +17 -0
  82. package/dist/components/Resizable/footerPanelUtils.d.ts +25 -0
  83. package/dist/components/Resizable/footerPanelUtils.d.ts.map +1 -0
  84. package/dist/components/Resizable/footerPanelUtils.js +61 -0
  85. package/dist/components/Resizable/index.d.ts +4 -0
  86. package/dist/components/Resizable/index.d.ts.map +1 -0
  87. package/dist/components/Resizable/index.js +3 -0
  88. package/dist/components/Resizable/useResizable.d.ts +42 -0
  89. package/dist/components/Resizable/useResizable.d.ts.map +1 -0
  90. package/dist/components/Resizable/useResizable.js +151 -0
  91. package/dist/components/ResourceList/index.d.ts +73 -0
  92. package/dist/components/ResourceList/index.d.ts.map +1 -0
  93. package/dist/components/ResourceList/index.js +44 -0
  94. package/dist/components/RowActionsMenu/index.d.ts +33 -0
  95. package/dist/components/RowActionsMenu/index.d.ts.map +1 -0
  96. package/dist/components/RowActionsMenu/index.js +54 -0
  97. package/dist/components/SegmentedTabs/index.d.ts +107 -0
  98. package/dist/components/SegmentedTabs/index.d.ts.map +1 -0
  99. package/dist/components/SegmentedTabs/index.js +111 -0
  100. package/dist/components/Spinner/index.d.ts +26 -0
  101. package/dist/components/Spinner/index.d.ts.map +1 -0
  102. package/dist/components/Spinner/index.js +22 -0
  103. package/dist/components/StatusMessage/index.d.ts +29 -0
  104. package/dist/components/StatusMessage/index.d.ts.map +1 -0
  105. package/dist/components/StatusMessage/index.js +13 -0
  106. package/dist/components/TabCloseButton/index.d.ts +25 -0
  107. package/dist/components/TabCloseButton/index.d.ts.map +1 -0
  108. package/dist/components/TabCloseButton/index.js +13 -0
  109. package/dist/components/VariableInput/index.d.ts +58 -0
  110. package/dist/components/VariableInput/index.d.ts.map +1 -0
  111. package/dist/components/VariableInput/index.js +90 -0
  112. package/dist/components/VariableTable/index.d.ts +22 -0
  113. package/dist/components/VariableTable/index.d.ts.map +1 -0
  114. package/dist/components/VariableTable/index.js +43 -0
  115. package/dist/components/classes.d.ts +11 -0
  116. package/dist/components/classes.d.ts.map +1 -0
  117. package/dist/components/classes.js +14 -0
  118. package/dist/components/forms/Input.d.ts +22 -0
  119. package/dist/components/forms/Input.d.ts.map +1 -0
  120. package/dist/components/forms/Input.js +9 -0
  121. package/dist/components/forms/Select.d.ts +24 -0
  122. package/dist/components/forms/Select.d.ts.map +1 -0
  123. package/dist/components/forms/Select.js +10 -0
  124. package/dist/components/forms/Textarea.d.ts +22 -0
  125. package/dist/components/forms/Textarea.d.ts.map +1 -0
  126. package/dist/components/forms/Textarea.js +8 -0
  127. package/dist/components/forms/classes.d.ts +24 -0
  128. package/dist/components/forms/classes.d.ts.map +1 -0
  129. package/dist/components/forms/classes.js +32 -0
  130. package/dist/components/forms/index.d.ts +5 -0
  131. package/dist/components/forms/index.d.ts.map +1 -0
  132. package/dist/components/forms/index.js +4 -0
  133. package/dist/components/index.d.ts +51 -0
  134. package/dist/components/index.d.ts.map +1 -0
  135. package/dist/components/index.js +37 -0
  136. package/dist/components/rowActionsMenuHelpers.d.ts +13 -0
  137. package/dist/components/rowActionsMenuHelpers.d.ts.map +1 -0
  138. package/dist/components/rowActionsMenuHelpers.js +29 -0
  139. package/dist/components/useDialogFocus.d.ts +16 -0
  140. package/dist/components/useDialogFocus.d.ts.map +1 -0
  141. package/dist/components/useDialogFocus.js +81 -0
  142. package/dist/components/utils.d.ts +29 -0
  143. package/dist/components/utils.d.ts.map +1 -0
  144. package/dist/components/utils.js +89 -0
  145. package/dist/components/utils.test.d.ts +2 -0
  146. package/dist/components/utils.test.d.ts.map +1 -0
  147. package/dist/components/utils.test.js +27 -0
  148. package/dist/http/substitute.d.ts.map +1 -1
  149. package/dist/http/substitute.js +9 -3
  150. package/dist/http/substitute.test.js +8 -0
  151. package/dist/main.d.ts +1 -1
  152. package/dist/main.d.ts.map +1 -1
  153. package/dist/runtime/react.d.ts +16 -1
  154. package/dist/runtime/react.js +40 -0
  155. package/dist/types.d.ts +168 -0
  156. package/dist/types.d.ts.map +1 -1
  157. package/dist/ui/codeEditorSettings.d.ts +29 -0
  158. package/dist/ui/codeEditorSettings.d.ts.map +1 -0
  159. package/dist/ui/codeEditorSettings.js +52 -0
  160. package/dist/ui/index.d.ts +1 -0
  161. package/dist/ui/index.d.ts.map +1 -1
  162. package/dist/ui/index.js +1 -0
  163. package/dist/variables/dynamic.d.ts +49 -0
  164. package/dist/variables/dynamic.d.ts.map +1 -0
  165. package/dist/variables/dynamic.js +735 -0
  166. package/dist/variables/dynamic.test.d.ts +2 -0
  167. package/dist/variables/dynamic.test.d.ts.map +1 -0
  168. package/dist/variables/dynamic.test.js +60 -0
  169. package/dist/variables/index.d.ts +3 -0
  170. package/dist/variables/index.d.ts.map +1 -0
  171. package/dist/variables/index.js +2 -0
  172. package/dist/variables/tokens.d.ts +44 -0
  173. package/dist/variables/tokens.d.ts.map +1 -0
  174. package/dist/variables/tokens.js +76 -0
  175. package/dist/variables/tokens.test.d.ts +2 -0
  176. package/dist/variables/tokens.test.d.ts.map +1 -0
  177. package/dist/variables/tokens.test.js +115 -0
  178. package/package.json +75 -14
@@ -0,0 +1,319 @@
1
+ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
2
+ import { autocompletion } from '@codemirror/autocomplete';
3
+ import { javascript } from '@codemirror/lang-javascript';
4
+ import { json } from '@codemirror/lang-json';
5
+ import { HighlightStyle, StreamLanguage, syntaxHighlighting } from '@codemirror/language';
6
+ import { shell } from '@codemirror/legacy-modes/mode/shell';
7
+ import { Decoration, EditorView, MatchDecorator, ViewPlugin, hoverTooltip } from '@codemirror/view';
8
+ import CodeMirrorImport from '@uiw/react-codemirror';
9
+ import { tags } from '@lezer/highlight';
10
+ import { useEffect, useMemo, useState, createElement } from '@harborclient/sdk/react';
11
+ import { getDynamicVariableDescription, resolveVariable, VARIABLE_NAME_CHARS } from '../../variables/index.js';
12
+ import { useCodeEditorConfig } from './config.js';
13
+ import { getCodeEditorThemeExtension } from './themes.js';
14
+ export { CODE_EDITOR_THEME_OPTIONS } from './themes.js';
15
+ const lightHighlight = HighlightStyle.define([
16
+ { tag: tags.propertyName, color: '#881391' },
17
+ { tag: tags.string, color: '#c41a16' },
18
+ { tag: tags.number, color: '#1c00cf' },
19
+ { tag: tags.bool, color: '#1c00cf' },
20
+ { tag: tags.null, color: '#1c00cf' },
21
+ { tag: tags.keyword, color: '#881391' },
22
+ { tag: tags.bracket, color: 'var(--mac-text)' },
23
+ { tag: tags.punctuation, color: 'var(--mac-muted)' },
24
+ { tag: tags.comment, color: 'var(--mac-muted)', fontStyle: 'italic' }
25
+ ]);
26
+ const darkHighlight = HighlightStyle.define([
27
+ { tag: tags.propertyName, color: '#ff7ab2' },
28
+ { tag: tags.string, color: '#ff8170' },
29
+ { tag: tags.number, color: '#78dce8' },
30
+ { tag: tags.bool, color: '#78dce8' },
31
+ { tag: tags.null, color: '#78dce8' },
32
+ { tag: tags.keyword, color: '#ff7ab2' },
33
+ { tag: tags.bracket, color: 'var(--mac-text)' },
34
+ { tag: tags.punctuation, color: 'var(--mac-muted)' },
35
+ { tag: tags.comment, color: 'var(--mac-muted)', fontStyle: 'italic' }
36
+ ]);
37
+ const editorTheme = EditorView.theme({
38
+ '&': {
39
+ backgroundColor: 'transparent',
40
+ color: 'var(--mac-text)'
41
+ },
42
+ '.cm-scroller': {
43
+ overflow: 'auto',
44
+ fontFamily: 'var(--font-mono)'
45
+ },
46
+ '.cm-content': {
47
+ padding: '8px 0',
48
+ fontFamily: 'var(--font-mono)',
49
+ fontSize: '14px',
50
+ caretColor: 'var(--mac-accent)'
51
+ },
52
+ '.cm-line': {
53
+ padding: '0 8px'
54
+ },
55
+ '&.cm-focused': {
56
+ outline: 'none'
57
+ },
58
+ '&.cm-focused .cm-cursor': {
59
+ borderLeftColor: 'var(--mac-accent)'
60
+ },
61
+ '.cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection': {
62
+ backgroundColor: 'var(--mac-selection) !important'
63
+ },
64
+ '.cm-gutters': {
65
+ backgroundColor: 'transparent',
66
+ color: 'var(--mac-muted)',
67
+ border: 'none'
68
+ },
69
+ '.cm-activeLineGutter': {
70
+ backgroundColor: 'var(--mac-selection)'
71
+ },
72
+ '.cm-activeLine': {
73
+ backgroundColor: 'color-mix(in srgb, var(--mac-selection) 45%, transparent)'
74
+ },
75
+ '.cm-variable-token': {
76
+ color: '#32D2E2'
77
+ },
78
+ '.cm-tooltip.cm-tooltip-hover': {
79
+ border: '1px solid var(--mac-separator)',
80
+ backgroundColor: 'var(--mac-surface)',
81
+ borderRadius: '6px',
82
+ boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
83
+ },
84
+ '.cm-variable-tooltip': {
85
+ display: 'flex',
86
+ flexDirection: 'column',
87
+ gap: '6px',
88
+ padding: '8px 12px',
89
+ fontSize: '14px',
90
+ color: 'var(--mac-text)'
91
+ },
92
+ '.cm-variable-tooltip-muted': {
93
+ color: 'var(--mac-muted)'
94
+ },
95
+ '.cm-variable-tooltip-edit': {
96
+ alignSelf: 'flex-start',
97
+ background: 'none',
98
+ border: 'none',
99
+ padding: '0',
100
+ cursor: 'pointer',
101
+ fontSize: '14px',
102
+ color: 'var(--mac-accent)'
103
+ },
104
+ '.cm-tooltip.cm-tooltip-autocomplete': {
105
+ border: '1px solid var(--mac-separator)',
106
+ backgroundColor: 'var(--mac-surface)',
107
+ borderRadius: '6px',
108
+ boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
109
+ fontSize: '14px'
110
+ },
111
+ '.cm-completionLabel': {
112
+ fontFamily: 'var(--font-mono)'
113
+ },
114
+ '.cm-completionDetail': {
115
+ color: 'var(--mac-muted)',
116
+ fontStyle: 'normal',
117
+ marginLeft: '8px'
118
+ }
119
+ });
120
+ const variableMatcher = new MatchDecorator({
121
+ regexp: new RegExp(`\\{\\{\\s*([${VARIABLE_NAME_CHARS}]+)\\s*\\}\\}`, 'g'),
122
+ decoration: Decoration.mark({ class: 'cm-variable-token' })
123
+ });
124
+ const variableHighlighter = ViewPlugin.fromClass(class {
125
+ decorations;
126
+ /**
127
+ * Builds the initial {{variable}} decoration set for the editor view.
128
+ *
129
+ * @param view - CodeMirror editor view instance.
130
+ */
131
+ constructor(view) {
132
+ this.decorations = variableMatcher.createDeco(view);
133
+ }
134
+ /**
135
+ * Recomputes decorations when document content or viewport changes.
136
+ *
137
+ * @param update - View update describing what changed.
138
+ */
139
+ update(update) {
140
+ this.decorations = variableMatcher.updateDeco(update, this.decorations);
141
+ }
142
+ }, { decorations: (v) => v.decorations });
143
+ /**
144
+ * Builds a hover tooltip extension for {{variable}} tokens.
145
+ *
146
+ * @param variables - Collection-scoped variables for resolution.
147
+ * @param onEditVariable - Optional callback to open collection settings.
148
+ */
149
+ function variableTooltip(variables, onEditVariable) {
150
+ return hoverTooltip((view, pos) => {
151
+ const line = view.state.doc.lineAt(pos);
152
+ const pattern = new RegExp(`\\{\\{\\s*([${VARIABLE_NAME_CHARS}]+)\\s*\\}\\}`, 'g');
153
+ for (const match of line.text.matchAll(pattern)) {
154
+ const start = line.from + (match.index ?? 0);
155
+ const end = start + match[0].length;
156
+ if (pos < start || pos > end)
157
+ continue;
158
+ const key = match[1];
159
+ const value = resolveVariable(key, variables);
160
+ const dynamicDescription = getDynamicVariableDescription(key);
161
+ return {
162
+ pos: start,
163
+ end,
164
+ above: true,
165
+ create() {
166
+ const dom = document.createElement('div');
167
+ dom.className = 'cm-variable-tooltip';
168
+ const valueEl = document.createElement('div');
169
+ if (value !== undefined) {
170
+ valueEl.textContent = value;
171
+ }
172
+ else if (dynamicDescription) {
173
+ valueEl.textContent = `Dynamic: ${dynamicDescription}`;
174
+ }
175
+ else {
176
+ valueEl.textContent = 'Not defined';
177
+ valueEl.className = 'cm-variable-tooltip-muted';
178
+ }
179
+ dom.appendChild(valueEl);
180
+ if (onEditVariable) {
181
+ const btn = document.createElement('button');
182
+ btn.type = 'button';
183
+ btn.textContent = 'Edit value';
184
+ btn.className = 'cm-variable-tooltip-edit';
185
+ btn.addEventListener('mousedown', (e) => {
186
+ e.preventDefault();
187
+ onEditVariable();
188
+ });
189
+ dom.appendChild(btn);
190
+ }
191
+ return { dom };
192
+ }
193
+ };
194
+ }
195
+ return null;
196
+ });
197
+ }
198
+ /**
199
+ * CodeMirror wrapper for editable request bodies and read-only response views.
200
+ *
201
+ * Styling relies on host CSS variables (`--mac-*`, `--font-mono`) and the `.app-no-drag`
202
+ * class defined in HarborClient `styles.css`.
203
+ */
204
+ export function CodeEditor({ value, onChange, language = 'text', readOnly = false, placeholder, minHeight = '144px', className = '', variables, onEditVariable, completionSource, themeOverride, setupOverride, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy }) {
205
+ const config = useCodeEditorConfig();
206
+ const resolvedTheme = themeOverride ?? config.theme;
207
+ const resolvedSetup = setupOverride ?? (readOnly ? null : config.setup);
208
+ const [isDark, setIsDark] = useState(() => window.matchMedia('(prefers-color-scheme: dark)').matches);
209
+ /**
210
+ * Tracks system dark mode so syntax highlighting matches the active theme.
211
+ */
212
+ useEffect(() => {
213
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
214
+ const handleChange = () => setIsDark(media.matches);
215
+ media.addEventListener('change', handleChange);
216
+ return () => media.removeEventListener('change', handleChange);
217
+ }, []);
218
+ /**
219
+ * Assembles CodeMirror extensions for language mode, theme, and optional variable tooling.
220
+ */
221
+ const extensions = useMemo(() => {
222
+ const next = [EditorView.lineWrapping, editorTheme];
223
+ const themeExtension = getCodeEditorThemeExtension(resolvedTheme);
224
+ if (themeExtension) {
225
+ next.push(themeExtension);
226
+ }
227
+ else {
228
+ next.push(syntaxHighlighting(isDark ? darkHighlight : lightHighlight));
229
+ }
230
+ if (language === 'json') {
231
+ next.push(json());
232
+ }
233
+ if (language === 'javascript') {
234
+ next.push(javascript());
235
+ if (completionSource) {
236
+ next.push(autocompletion({
237
+ activateOnTyping: true,
238
+ override: [completionSource]
239
+ }));
240
+ }
241
+ }
242
+ if (language === 'shell') {
243
+ next.push(StreamLanguage.define(shell));
244
+ }
245
+ if (variables) {
246
+ next.push(variableHighlighter, variableTooltip(variables, onEditVariable));
247
+ }
248
+ const contentAttrs = {};
249
+ if (id)
250
+ contentAttrs.id = id;
251
+ if (ariaLabel)
252
+ contentAttrs['aria-label'] = ariaLabel;
253
+ if (ariaLabelledBy)
254
+ contentAttrs['aria-labelledby'] = ariaLabelledBy;
255
+ if (Object.keys(contentAttrs).length > 0) {
256
+ next.push(EditorView.contentAttributes.of(contentAttrs));
257
+ }
258
+ return next;
259
+ }, [
260
+ resolvedTheme,
261
+ isDark,
262
+ language,
263
+ variables,
264
+ onEditVariable,
265
+ completionSource,
266
+ id,
267
+ ariaLabel,
268
+ ariaLabelledBy
269
+ ]);
270
+ /**
271
+ * Resolves CodeMirror basicSetup from persisted settings or read-only defaults.
272
+ */
273
+ const basicSetup = useMemo(() => {
274
+ if (!resolvedSetup) {
275
+ return {
276
+ lineNumbers: false,
277
+ foldGutter: false,
278
+ highlightActiveLine: false,
279
+ highlightActiveLineGutter: false,
280
+ highlightSelectionMatches: false,
281
+ autocompletion: false,
282
+ closeBrackets: false,
283
+ indentOnInput: false
284
+ };
285
+ }
286
+ if (readOnly) {
287
+ return {
288
+ lineNumbers: resolvedSetup.lineNumbers,
289
+ foldGutter: resolvedSetup.foldGutter,
290
+ highlightActiveLine: resolvedSetup.highlightActiveLine,
291
+ highlightActiveLineGutter: resolvedSetup.highlightActiveLineGutter,
292
+ highlightSelectionMatches: false,
293
+ autocompletion: false,
294
+ closeBrackets: false,
295
+ indentOnInput: false
296
+ };
297
+ }
298
+ return {
299
+ lineNumbers: resolvedSetup.lineNumbers,
300
+ foldGutter: resolvedSetup.foldGutter,
301
+ highlightActiveLine: resolvedSetup.highlightActiveLine,
302
+ highlightActiveLineGutter: resolvedSetup.highlightActiveLineGutter
303
+ };
304
+ }, [resolvedSetup, readOnly]);
305
+ const wrapperClassName = readOnly
306
+ ? `overflow-hidden rounded-md bg-control shadow-[inset_0_0.5px_1px_rgba(0,0,0,0.06)] app-no-drag ${className}`
307
+ : `min-h-36 resize-y overflow-hidden rounded-md border border-separator bg-control shadow-[inset_0_0.5px_1px_rgba(0,0,0,0.06)] focus-within:shadow-[0_0_0_3px_color-mix(in_srgb,var(--mac-accent)_35%,transparent),inset_0_0.5px_1px_rgba(0,0,0,0.06)] app-no-drag ${className}`;
308
+ return (_jsx("div", { className: wrapperClassName, children: createElement(CodeMirrorImport, {
309
+ value,
310
+ onChange: readOnly ? undefined : onChange,
311
+ extensions,
312
+ theme: 'none',
313
+ editable: !readOnly,
314
+ readOnly,
315
+ placeholder,
316
+ minHeight,
317
+ basicSetup
318
+ }) }));
319
+ }
@@ -0,0 +1,19 @@
1
+ import type { Extension } from '@codemirror/state';
2
+ import type { CodeEditorTheme } from '../../types.js';
3
+ import { CODE_EDITOR_THEME_IDS } from '../../ui/codeEditorSettings.js';
4
+ export { CODE_EDITOR_THEME_IDS };
5
+ /**
6
+ * Theme options shown in the syntax highlighting settings dropdown.
7
+ */
8
+ export declare const CODE_EDITOR_THEME_OPTIONS: Array<{
9
+ value: CodeEditorTheme;
10
+ label: string;
11
+ }>;
12
+ /**
13
+ * Returns the CodeMirror theme extension for a settings value, or null for the built-in look.
14
+ *
15
+ * @param value - Persisted or selected theme identifier.
16
+ * @returns Theme extension to append to the editor, or null when using built-in highlighting.
17
+ */
18
+ export declare function getCodeEditorThemeExtension(value: CodeEditorTheme): Extension | null;
19
+ //# sourceMappingURL=themes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../../src/components/CodeEditor/themes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAUnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAStF,CAAC;AAYF;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAKpF"}
@@ -0,0 +1,37 @@
1
+ import { dracula, githubDark, githubLight, monokai, nord, solarizedLight, tokyoNight } from '@uiw/codemirror-themes-all';
2
+ import { CODE_EDITOR_THEME_IDS } from '../../ui/codeEditorSettings.js';
3
+ export { CODE_EDITOR_THEME_IDS };
4
+ /**
5
+ * Theme options shown in the syntax highlighting settings dropdown.
6
+ */
7
+ export const CODE_EDITOR_THEME_OPTIONS = [
8
+ { value: 'default', label: 'Default (built-in)' },
9
+ { value: 'dracula', label: 'Dracula' },
10
+ { value: 'githubLight', label: 'GitHub Light' },
11
+ { value: 'githubDark', label: 'GitHub Dark' },
12
+ { value: 'monokai', label: 'Monokai' },
13
+ { value: 'nord', label: 'Nord' },
14
+ { value: 'solarizedLight', label: 'Solarized Light' },
15
+ { value: 'tokyoNight', label: 'Tokyo Night' }
16
+ ];
17
+ const themeExtensions = {
18
+ dracula,
19
+ githubLight,
20
+ githubDark,
21
+ monokai,
22
+ nord,
23
+ solarizedLight,
24
+ tokyoNight
25
+ };
26
+ /**
27
+ * Returns the CodeMirror theme extension for a settings value, or null for the built-in look.
28
+ *
29
+ * @param value - Persisted or selected theme identifier.
30
+ * @returns Theme extension to append to the editor, or null when using built-in highlighting.
31
+ */
32
+ export function getCodeEditorThemeExtension(value) {
33
+ if (value === 'default') {
34
+ return null;
35
+ }
36
+ return themeExtensions[value];
37
+ }
@@ -0,0 +1,26 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ type EmptyStateVariant = 'inline' | 'centered';
3
+ interface Props {
4
+ /**
5
+ * Empty-state message content.
6
+ */
7
+ children: ReactNode;
8
+ /**
9
+ * Layout preset; centered fills available space in panel bodies.
10
+ */
11
+ variant?: EmptyStateVariant;
12
+ /**
13
+ * Additional Tailwind classes merged onto the wrapper element.
14
+ */
15
+ className?: string;
16
+ }
17
+ /**
18
+ * Placeholder shown when a panel or list has no content to display.
19
+ *
20
+ * @param children - Empty message text or markup.
21
+ * @param variant - Layout preset (`inline` or `centered`).
22
+ * @param className - Extra classes appended after the preset.
23
+ */
24
+ export declare function EmptyState({ children, variant, className }: Props): JSX.Element;
25
+ export {};
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/EmptyState/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,KAAK,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C,UAAU,KAAK;IACb;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAeD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAkB,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAK1F"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
2
+ /**
3
+ * Returns layout classes for inline or centered empty placeholders.
4
+ *
5
+ * @param variant - Empty state layout preset.
6
+ * @returns Tailwind classes for the wrapper.
7
+ */
8
+ function variantClasses(variant) {
9
+ if (variant === 'centered') {
10
+ return 'flex flex-1 items-center justify-center p-4 text-center text-[14px] text-muted';
11
+ }
12
+ return 'text-[14px] text-muted';
13
+ }
14
+ /**
15
+ * Placeholder shown when a panel or list has no content to display.
16
+ *
17
+ * @param children - Empty message text or markup.
18
+ * @param variant - Layout preset (`inline` or `centered`).
19
+ * @param className - Extra classes appended after the preset.
20
+ */
21
+ export function EmptyState({ children, variant = 'inline', className }) {
22
+ const base = variantClasses(variant);
23
+ const classes = className ? `${base} ${className}` : base;
24
+ return _jsx("div", { className: classes, children: children });
25
+ }
@@ -0,0 +1,22 @@
1
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2
+ import type { JSX } from 'react';
3
+ interface Props {
4
+ /**
5
+ * Font Awesome icon definition registered in the library.
6
+ */
7
+ icon: IconDefinition;
8
+ /**
9
+ * Optional Tailwind or custom classes for sizing and color.
10
+ */
11
+ className?: string;
12
+ /**
13
+ * When set, the icon is exposed to assistive tech instead of being decorative.
14
+ */
15
+ title?: string;
16
+ }
17
+ /**
18
+ * Renders a Font Awesome SVG icon with consistent default sizing.
19
+ */
20
+ export declare function FaIcon({ icon, className, title }: Props): JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FaIcon/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,SAAyB,EAAE,KAAK,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAOrF"}
@@ -0,0 +1,13 @@
1
+ import { createElement } from '@harborclient/sdk/react';
2
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
+ /**
4
+ * Renders a Font Awesome SVG icon with consistent default sizing.
5
+ */
6
+ export function FaIcon({ icon, className = 'h-3.5 w-3.5', title }) {
7
+ return createElement(FontAwesomeIcon, {
8
+ icon,
9
+ className,
10
+ title,
11
+ 'aria-hidden': title ? undefined : true
12
+ });
13
+ }
@@ -0,0 +1,39 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ /**
3
+ * Vertical spacing preset for inline error text.
4
+ */
5
+ export type FieldErrorSpacing = 'field' | 'section' | 'modal';
6
+ interface Props {
7
+ /**
8
+ * Error message content. When empty, nothing is rendered.
9
+ */
10
+ children?: ReactNode;
11
+ /**
12
+ * Element id referenced by `aria-describedby` on the related control.
13
+ */
14
+ id?: string;
15
+ /**
16
+ * Margin preset matching common form, section, and modal layouts.
17
+ */
18
+ spacing?: FieldErrorSpacing;
19
+ /**
20
+ * When true, exposes the message as an alert for assistive technologies.
21
+ */
22
+ roleAlert?: boolean;
23
+ /**
24
+ * Additional Tailwind classes merged onto the error paragraph.
25
+ */
26
+ className?: string;
27
+ }
28
+ /**
29
+ * Accessible inline validation or error text with consistent typography and spacing.
30
+ *
31
+ * @param children - Error message; omitted or empty values render nothing.
32
+ * @param id - Optional id for `aria-describedby` linkage.
33
+ * @param spacing - Margin preset (`field`, `section`, or `modal`).
34
+ * @param roleAlert - Whether to set `role="alert"`.
35
+ * @param className - Extra classes appended after the preset.
36
+ */
37
+ export declare function FieldError({ children, id, spacing, roleAlert, className }: Props): JSX.Element | null;
38
+ export {};
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FieldError/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAE9D,UAAU,KAAK;IACb;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,EAAE,EACF,OAAiB,EACjB,SAAiB,EACjB,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAW5B"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
2
+ /**
3
+ * Returns margin classes for the chosen error spacing preset.
4
+ *
5
+ * @param spacing - Vertical spacing preset.
6
+ * @returns Tailwind margin classes for the error paragraph.
7
+ */
8
+ function spacingClasses(spacing) {
9
+ switch (spacing) {
10
+ case 'section':
11
+ return 'mt-3';
12
+ case 'modal':
13
+ return 'mt-4';
14
+ case 'field':
15
+ default:
16
+ return 'mt-1';
17
+ }
18
+ }
19
+ /**
20
+ * Accessible inline validation or error text with consistent typography and spacing.
21
+ *
22
+ * @param children - Error message; omitted or empty values render nothing.
23
+ * @param id - Optional id for `aria-describedby` linkage.
24
+ * @param spacing - Margin preset (`field`, `section`, or `modal`).
25
+ * @param roleAlert - Whether to set `role="alert"`.
26
+ * @param className - Extra classes appended after the preset.
27
+ */
28
+ export function FieldError({ children, id, spacing = 'field', roleAlert = false, className }) {
29
+ if (children == null || children === '')
30
+ return null;
31
+ const base = `${spacingClasses(spacing)} text-[14px] text-danger`;
32
+ const classes = className ? `${base} ${className}` : base;
33
+ return (_jsx("p", { id: id, className: classes, role: roleAlert ? 'alert' : undefined, children: children }));
34
+ }
@@ -0,0 +1,30 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ interface Props {
3
+ /**
4
+ * Whether the associated slide-up panel is currently open.
5
+ */
6
+ active: boolean;
7
+ /**
8
+ * Called when the user activates the footer segment button.
9
+ */
10
+ onClick: () => void;
11
+ /**
12
+ * Panel element id referenced by `aria-controls`.
13
+ */
14
+ controlsId: string;
15
+ /**
16
+ * Button label and optional count badge content.
17
+ */
18
+ children: ReactNode;
19
+ /**
20
+ * Additional Tailwind classes merged onto the button element.
21
+ */
22
+ className?: string;
23
+ }
24
+ /**
25
+ * Text segment toggle button for the window footer bar, used to open and close
26
+ * slide-up panels such as Console and Variables.
27
+ */
28
+ export declare function FooterButton({ active, onClick, controlsId, children, className }: Props): JSX.Element;
29
+ export {};
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FooterButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,OAAO,EACP,UAAU,EACV,QAAQ,EACR,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAcrB"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
2
+ /**
3
+ * Compact segment button styles for the footer bar.
4
+ *
5
+ * @param active - Whether the associated panel is currently expanded.
6
+ */
7
+ function footerSegment(active) {
8
+ return active
9
+ ? 'cursor-pointer rounded-[5px] border-none bg-surface px-2 py-0.5 text-[14px] text-text shadow-sm app-no-drag'
10
+ : 'cursor-pointer rounded-[5px] border-none bg-transparent px-2 py-0.5 text-[14px] text-muted hover:text-text app-no-drag';
11
+ }
12
+ /**
13
+ * Text segment toggle button for the window footer bar, used to open and close
14
+ * slide-up panels such as Console and Variables.
15
+ */
16
+ export function FooterButton({ active, onClick, controlsId, children, className }) {
17
+ const classes = className ? `${footerSegment(active)} ${className}` : footerSegment(active);
18
+ return (_jsx("button", { type: "button", className: classes, onClick: onClick, "aria-expanded": active, "aria-controls": controlsId, children: children }));
19
+ }
@@ -0,0 +1,32 @@
1
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2
+ import type { JSX } from 'react';
3
+ interface Props {
4
+ /**
5
+ * Font Awesome icon shown inside the footer toggle button.
6
+ */
7
+ icon: IconDefinition;
8
+ /**
9
+ * Whether the associated panel or sidebar is currently open.
10
+ */
11
+ active: boolean;
12
+ /**
13
+ * Called when the user activates the toggle button.
14
+ */
15
+ onClick: () => void;
16
+ /**
17
+ * Noun phrase for accessibility labels, e.g. `"sidebar"` becomes
18
+ * `"Hide sidebar"` / `"Show sidebar"`.
19
+ */
20
+ label: string;
21
+ /**
22
+ * Additional Tailwind classes merged onto the button element.
23
+ */
24
+ className?: string;
25
+ }
26
+ /**
27
+ * Icon-only toggle button for the window footer bar, used to show or hide
28
+ * sidebars and similar panels.
29
+ */
30
+ export declare function FooterIcon({ icon, active, onClick, label, className }: Props): JSX.Element;
31
+ export {};
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FooterIcon/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAgB1F"}