@harborclient/sdk 1.0.57 → 1.0.59
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.
- package/dist/components/CodeEditor/index.d.ts +56 -1
- package/dist/components/CodeEditor/index.d.ts.map +1 -1
- package/dist/components/CodeEditor/index.js +280 -2
- package/dist/components/SegmentedTabs/index.js +2 -2
- package/dist/components/Toolbar/index.d.ts +7 -3
- package/dist/components/Toolbar/index.d.ts.map +1 -1
- package/dist/components/Toolbar/index.js +21 -7
- package/dist/components/VariableInput/index.d.ts.map +1 -1
- package/dist/components/VariableInput/index.js +53 -14
- package/dist/components/VisibilityMenu/index.d.ts +34 -0
- package/dist/components/VisibilityMenu/index.d.ts.map +1 -0
- package/dist/components/{SegmentedTabs/SegmentedTabsVisibilityMenu.js → VisibilityMenu/index.js} +15 -15
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/package.json +1 -1
- package/dist/components/SegmentedTabs/SegmentedTabsVisibilityMenu.d.ts +0 -22
- package/dist/components/SegmentedTabs/SegmentedTabsVisibilityMenu.d.ts.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type CompletionSource } from '@codemirror/autocomplete';
|
|
2
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
2
3
|
import type { ComponentPropsWithoutRef, JSX } from 'react';
|
|
3
4
|
import type { CodeEditorSetup, CodeEditorTheme, Variable } from '../../types.js';
|
|
4
5
|
export { CODE_EDITOR_THEME_OPTIONS } from './themes.js';
|
|
@@ -92,6 +93,56 @@ export interface CodeEditorViewState {
|
|
|
92
93
|
*/
|
|
93
94
|
selection: CodeEditorSelectionRange;
|
|
94
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Selected text range passed to {@link CodeEditorSelectionAction.onSelect}.
|
|
98
|
+
*/
|
|
99
|
+
export interface CodeEditorTextSelection {
|
|
100
|
+
/**
|
|
101
|
+
* Selected document text.
|
|
102
|
+
*/
|
|
103
|
+
text: string;
|
|
104
|
+
/**
|
|
105
|
+
* Start offset (inclusive) in the document.
|
|
106
|
+
*/
|
|
107
|
+
from: number;
|
|
108
|
+
/**
|
|
109
|
+
* End offset (exclusive) in the document.
|
|
110
|
+
*/
|
|
111
|
+
to: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* One action offered in the floating toolbar when the user selects text.
|
|
115
|
+
*/
|
|
116
|
+
export interface CodeEditorSelectionAction {
|
|
117
|
+
/**
|
|
118
|
+
* Stable action id for host routing.
|
|
119
|
+
*/
|
|
120
|
+
id: string;
|
|
121
|
+
/**
|
|
122
|
+
* Visible button label.
|
|
123
|
+
*/
|
|
124
|
+
label: string;
|
|
125
|
+
/**
|
|
126
|
+
* Accessible name for the action button.
|
|
127
|
+
*/
|
|
128
|
+
ariaLabel: string;
|
|
129
|
+
/**
|
|
130
|
+
* Called when the user activates this action on the current selection.
|
|
131
|
+
*/
|
|
132
|
+
onSelect: (selection: CodeEditorTextSelection) => void;
|
|
133
|
+
/**
|
|
134
|
+
* Optional leading icon shown before the action label.
|
|
135
|
+
*/
|
|
136
|
+
icon?: IconDefinition;
|
|
137
|
+
/**
|
|
138
|
+
* Optional shortcut hint shown after the label (for example `Ctrl+L`).
|
|
139
|
+
*/
|
|
140
|
+
shortcutHint?: string;
|
|
141
|
+
/**
|
|
142
|
+
* Optional CodeMirror key binding that triggers this action on the current selection.
|
|
143
|
+
*/
|
|
144
|
+
key?: string;
|
|
145
|
+
}
|
|
95
146
|
export interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'onChange' | 'className' | 'id' | 'aria-label' | 'aria-labelledby' | 'aria-invalid' | 'aria-describedby' | 'style'> {
|
|
96
147
|
/**
|
|
97
148
|
* Editor content.
|
|
@@ -172,6 +223,10 @@ export interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
|
|
|
172
223
|
* Called when the user presses Enter on a complete slash command line.
|
|
173
224
|
*/
|
|
174
225
|
onSlashCommand?: (trigger: CodeEditorSlashTrigger) => void;
|
|
226
|
+
/**
|
|
227
|
+
* Actions shown in a floating toolbar when the user selects non-empty text.
|
|
228
|
+
*/
|
|
229
|
+
selectionActions?: CodeEditorSelectionAction[];
|
|
175
230
|
/**
|
|
176
231
|
* When true, shows inline syntax-error squiggles for supported languages.
|
|
177
232
|
* Defaults to true.
|
|
@@ -216,5 +271,5 @@ export interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
|
|
|
216
271
|
* Styling relies on host CSS variables (`--mac-*`, `--font-mono`) and the `.app-no-drag`
|
|
217
272
|
* class defined in HarborClient `styles.css`.
|
|
218
273
|
*/
|
|
219
|
-
export declare function CodeEditor({ value, onChange, language, readOnly, editable, placeholder, placeholderHighlight, minHeight, height, onHeightChange, initialScrollTop, initialSelection, onViewStateChange, className, variables, onEditVariable, completionSource, slashCommands, onSlashCommand, lint, themeOverride, setupOverride, fontSize, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, ...props }: Props): JSX.Element;
|
|
274
|
+
export declare function CodeEditor({ value, onChange, language, readOnly, editable, placeholder, placeholderHighlight, minHeight, height, onHeightChange, initialScrollTop, initialSelection, onViewStateChange, className, variables, onEditVariable, completionSource, slashCommands, onSlashCommand, selectionActions, lint, themeOverride, setupOverride, fontSize, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, ...props }: Props): JSX.Element;
|
|
220
275
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/CodeEditor/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAmC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/CodeEditor/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,10 @@ import CodeMirrorImport from '@uiw/react-codemirror';
|
|
|
11
11
|
import { normalizeCodeEditorFontSize } from '../../ui/codeEditorSettings.js';
|
|
12
12
|
import { VARIABLE_NAME_CHARS, getVariableTooltipContent } from '../../variables/index.js';
|
|
13
13
|
import { Button } from '../Button/index.js';
|
|
14
|
+
import { FaIcon } from '../FaIcon/index.js';
|
|
14
15
|
import { buildVariableTooltipDom } from '../VariableTooltip/dom.js';
|
|
15
16
|
import { VariableTooltipValue } from '../VariableTooltip/index.js';
|
|
17
|
+
import { portalToBody } from '../portalToBody.js';
|
|
16
18
|
import { useCodeEditorConfig } from './config.js';
|
|
17
19
|
import { createBuiltInSyntaxHighlighting, createEditorTheme } from './editorChrome.js';
|
|
18
20
|
import { createSlashCommandHighlighter } from './slashCommandHighlighter.js';
|
|
@@ -34,6 +36,10 @@ function clampSelection(docLength, selection) {
|
|
|
34
36
|
}
|
|
35
37
|
/** Debounce interval for {@link Props.onViewStateChange} notifications. */
|
|
36
38
|
const VIEW_STATE_DEBOUNCE_MS = 300;
|
|
39
|
+
/** Delay before showing the selection action toolbar after selection settles. */
|
|
40
|
+
const SELECTION_TOOLBAR_SHOW_DELAY_MS = 450;
|
|
41
|
+
/** Extra viewport gap between the selection top edge and the portaled toolbar. */
|
|
42
|
+
const SELECTION_TOOLBAR_OFFSET_PX = 16;
|
|
37
43
|
const variableMatcher = new MatchDecorator({
|
|
38
44
|
regexp: new RegExp(`\\{\\{\\s*([${VARIABLE_NAME_CHARS}]+)\\s*\\}\\}`, 'g'),
|
|
39
45
|
decoration: Decoration.mark({ class: 'cm-variable-token' })
|
|
@@ -250,6 +256,210 @@ function variableTooltipEscapeHandler(isOpen, onDismiss, getValidationDescribedB
|
|
|
250
256
|
}
|
|
251
257
|
});
|
|
252
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Computes viewport anchor coordinates for the selection action toolbar.
|
|
261
|
+
*
|
|
262
|
+
* @param view - CodeMirror editor view.
|
|
263
|
+
* @param selectionFrom - Start offset (inclusive) of the selection.
|
|
264
|
+
* @param selectionTo - End offset (exclusive) of the selection.
|
|
265
|
+
* @returns Toolbar anchor position, or null when coords are unavailable.
|
|
266
|
+
*/
|
|
267
|
+
function computeSelectionActionToolbarCoords(view, selectionFrom, selectionTo) {
|
|
268
|
+
const startCoords = view.coordsAtPos(selectionFrom);
|
|
269
|
+
if (!startCoords) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
const endCoords = view.coordsAtPos(selectionTo);
|
|
273
|
+
const startCenter = startCoords.left + (startCoords.right - startCoords.left) / 2;
|
|
274
|
+
const endCenter = endCoords
|
|
275
|
+
? endCoords.left + (endCoords.right - endCoords.left) / 2
|
|
276
|
+
: startCenter;
|
|
277
|
+
return {
|
|
278
|
+
top: startCoords.top,
|
|
279
|
+
left: (startCenter + endCenter) / 2
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Builds update and pointer handlers that debounce toolbar display until selection settles.
|
|
284
|
+
*/
|
|
285
|
+
function createSelectionActionToolbarExtensions(onToolbarChange, isEnabled, isOpen, onDismiss) {
|
|
286
|
+
const controller = {
|
|
287
|
+
showTimer: undefined,
|
|
288
|
+
isPointerSelecting: false,
|
|
289
|
+
isToolbarOpen: false,
|
|
290
|
+
pendingState: null
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Clears a scheduled toolbar reveal without changing open state.
|
|
294
|
+
*/
|
|
295
|
+
const clearShowTimer = () => {
|
|
296
|
+
if (controller.showTimer) {
|
|
297
|
+
clearTimeout(controller.showTimer);
|
|
298
|
+
controller.showTimer = undefined;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Notifies React of toolbar visibility while keeping controller state in sync.
|
|
303
|
+
*/
|
|
304
|
+
const notifyToolbarChange = (state) => {
|
|
305
|
+
controller.isToolbarOpen = state != null;
|
|
306
|
+
if (state == null) {
|
|
307
|
+
controller.pendingState = null;
|
|
308
|
+
}
|
|
309
|
+
onToolbarChange(state);
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* Hides the toolbar immediately and cancels any pending reveal.
|
|
313
|
+
*/
|
|
314
|
+
const dismissToolbar = () => {
|
|
315
|
+
clearShowTimer();
|
|
316
|
+
if (controller.isToolbarOpen || controller.pendingState != null) {
|
|
317
|
+
notifyToolbarChange(null);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
/**
|
|
321
|
+
* Schedules toolbar display after the configured settle delay.
|
|
322
|
+
*/
|
|
323
|
+
const scheduleShow = (state) => {
|
|
324
|
+
controller.pendingState = state;
|
|
325
|
+
clearShowTimer();
|
|
326
|
+
if (controller.isPointerSelecting) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
controller.showTimer = setTimeout(() => {
|
|
330
|
+
controller.showTimer = undefined;
|
|
331
|
+
if (controller.isPointerSelecting) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
notifyToolbarChange(state);
|
|
335
|
+
}, SELECTION_TOOLBAR_SHOW_DELAY_MS);
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* Repositions or reveals the toolbar without waiting when it is already open.
|
|
339
|
+
*/
|
|
340
|
+
const showImmediately = (state) => {
|
|
341
|
+
clearShowTimer();
|
|
342
|
+
notifyToolbarChange(state);
|
|
343
|
+
};
|
|
344
|
+
const updateListener = EditorView.updateListener.of((update) => {
|
|
345
|
+
if (!isEnabled()) {
|
|
346
|
+
dismissToolbar();
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (!update.selectionSet && !update.docChanged && !update.viewportChanged) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const { from, to } = update.state.selection.main;
|
|
353
|
+
if (from === to) {
|
|
354
|
+
dismissToolbar();
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const selectionFrom = Math.min(from, to);
|
|
358
|
+
const selectionTo = Math.max(from, to);
|
|
359
|
+
const text = update.state.sliceDoc(selectionFrom, selectionTo);
|
|
360
|
+
if (!text.trim()) {
|
|
361
|
+
dismissToolbar();
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const coords = computeSelectionActionToolbarCoords(update.view, selectionFrom, selectionTo);
|
|
365
|
+
if (!coords) {
|
|
366
|
+
dismissToolbar();
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const nextState = {
|
|
370
|
+
top: coords.top,
|
|
371
|
+
left: coords.left,
|
|
372
|
+
text,
|
|
373
|
+
from: selectionFrom,
|
|
374
|
+
to: selectionTo
|
|
375
|
+
};
|
|
376
|
+
if (isOpen() && !update.selectionSet && update.viewportChanged) {
|
|
377
|
+
showImmediately(nextState);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (isOpen() && update.selectionSet) {
|
|
381
|
+
scheduleShow(nextState);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
scheduleShow(nextState);
|
|
385
|
+
});
|
|
386
|
+
const pointerGuard = EditorView.domEventHandlers({
|
|
387
|
+
/**
|
|
388
|
+
* Suppresses toolbar reveal while the user is drag-selecting with the primary button.
|
|
389
|
+
*/
|
|
390
|
+
pointerdown(event) {
|
|
391
|
+
if (event.button === 0) {
|
|
392
|
+
controller.isPointerSelecting = true;
|
|
393
|
+
clearShowTimer();
|
|
394
|
+
}
|
|
395
|
+
return false;
|
|
396
|
+
},
|
|
397
|
+
/**
|
|
398
|
+
* Resumes debounced reveal after drag-select completes.
|
|
399
|
+
*/
|
|
400
|
+
pointerup() {
|
|
401
|
+
controller.isPointerSelecting = false;
|
|
402
|
+
if (controller.pendingState != null && !isOpen()) {
|
|
403
|
+
scheduleShow(controller.pendingState);
|
|
404
|
+
}
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
const dismissHandler = EditorView.domEventHandlers({
|
|
409
|
+
keydown(event) {
|
|
410
|
+
if (event.key === 'Escape' && isOpen()) {
|
|
411
|
+
event.preventDefault();
|
|
412
|
+
dismissToolbar();
|
|
413
|
+
onDismiss();
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
const cleanupPlugin = ViewPlugin.fromClass(class {
|
|
420
|
+
/**
|
|
421
|
+
* Clears any pending toolbar reveal when the editor extension is destroyed.
|
|
422
|
+
*/
|
|
423
|
+
destroy() {
|
|
424
|
+
clearShowTimer();
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
return [updateListener, pointerGuard, dismissHandler, cleanupPlugin];
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Registers keyboard shortcuts for selection toolbar actions.
|
|
431
|
+
*
|
|
432
|
+
* @param actions - Selection actions that define a {@link CodeEditorSelectionAction.key}.
|
|
433
|
+
* @param onToolbarChange - Clears the floating toolbar after a shortcut fires.
|
|
434
|
+
*/
|
|
435
|
+
function createSelectionActionKeymap(actions, onToolbarChange) {
|
|
436
|
+
const keyedActions = actions.filter((action) => action.key);
|
|
437
|
+
if (keyedActions.length === 0) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
return Prec.highest(keymap.of(keyedActions.map((action) => ({
|
|
441
|
+
key: action.key,
|
|
442
|
+
run(view) {
|
|
443
|
+
const { from, to } = view.state.selection.main;
|
|
444
|
+
if (from === to) {
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
const selectionFrom = Math.min(from, to);
|
|
448
|
+
const selectionTo = Math.max(from, to);
|
|
449
|
+
const text = view.state.sliceDoc(selectionFrom, selectionTo);
|
|
450
|
+
if (!text.trim()) {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
action.onSelect({
|
|
454
|
+
text,
|
|
455
|
+
from: selectionFrom,
|
|
456
|
+
to: selectionTo
|
|
457
|
+
});
|
|
458
|
+
onToolbarChange(null);
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
}))));
|
|
462
|
+
}
|
|
253
463
|
/**
|
|
254
464
|
* Builds a hover tooltip extension for {{variable}} tokens.
|
|
255
465
|
*/
|
|
@@ -309,6 +519,13 @@ function buildCoreExtensions(options) {
|
|
|
309
519
|
if (options.hasVariables) {
|
|
310
520
|
next.push(variableHighlighter, variableTooltip(options.getVariables, options.getOnEditVariable), variableSelectionTooltip(options.tooltipId, options.onSelectionTooltipChange, options.getValidationDescribedBy), variableTooltipEscapeHandler(options.isSelectionTooltipOpen, options.onDismissSelectionTooltip, options.getValidationDescribedBy));
|
|
311
521
|
}
|
|
522
|
+
if (options.hasSelectionActions) {
|
|
523
|
+
next.push(...createSelectionActionToolbarExtensions(options.onSelectionActionToolbarChange, () => options.hasSelectionActions, options.isSelectionActionToolbarOpen, options.onDismissSelectionActionToolbar));
|
|
524
|
+
const keymapExtension = createSelectionActionKeymap(options.selectionActions, options.onSelectionActionToolbarChange);
|
|
525
|
+
if (keymapExtension) {
|
|
526
|
+
next.push(keymapExtension);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
312
529
|
return next;
|
|
313
530
|
}
|
|
314
531
|
/**
|
|
@@ -396,7 +613,7 @@ function buildPlaceholderExtensions(options) {
|
|
|
396
613
|
* Styling relies on host CSS variables (`--mac-*`, `--font-mono`) and the `.app-no-drag`
|
|
397
614
|
* class defined in HarborClient `styles.css`.
|
|
398
615
|
*/
|
|
399
|
-
export function CodeEditor({ value, onChange, language = 'text', readOnly = false, editable, placeholder, placeholderHighlight = false, minHeight = '144px', height, onHeightChange, initialScrollTop, initialSelection, onViewStateChange, className = '', variables, onEditVariable, completionSource, slashCommands, onSlashCommand, lint = true, themeOverride, setupOverride, fontSize, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, ...props }) {
|
|
616
|
+
export function CodeEditor({ value, onChange, language = 'text', readOnly = false, editable, placeholder, placeholderHighlight = false, minHeight = '144px', height, onHeightChange, initialScrollTop, initialSelection, onViewStateChange, className = '', variables, onEditVariable, completionSource, slashCommands, onSlashCommand, selectionActions, lint = true, themeOverride, setupOverride, fontSize, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, ...props }) {
|
|
400
617
|
const config = useCodeEditorConfig();
|
|
401
618
|
const resolvedTheme = themeOverride ?? config.theme;
|
|
402
619
|
const resolvedSetup = setupOverride ?? (readOnly ? null : config.setup);
|
|
@@ -408,6 +625,15 @@ export function CodeEditor({ value, onChange, language = 'text', readOnly = fals
|
|
|
408
625
|
selectionTooltipRef.current = selectionTooltip;
|
|
409
626
|
const setSelectionTooltipRef = useRef(setSelectionTooltip);
|
|
410
627
|
setSelectionTooltipRef.current = setSelectionTooltip;
|
|
628
|
+
const [selectionActionToolbar, setSelectionActionToolbar] = useState(null);
|
|
629
|
+
const selectionActionToolbarRef = useRef(selectionActionToolbar);
|
|
630
|
+
selectionActionToolbarRef.current = selectionActionToolbar;
|
|
631
|
+
const setSelectionActionToolbarRef = useRef(setSelectionActionToolbar);
|
|
632
|
+
setSelectionActionToolbarRef.current = setSelectionActionToolbar;
|
|
633
|
+
const selectionToolbarElementRef = useRef(null);
|
|
634
|
+
const selectionActionsRef = useRef(selectionActions);
|
|
635
|
+
selectionActionsRef.current = selectionActions;
|
|
636
|
+
const hasSelectionActions = selectionActions != null && selectionActions.length > 0;
|
|
411
637
|
const ariaDescribedByRef = useRef(ariaDescribedBy);
|
|
412
638
|
ariaDescribedByRef.current = ariaDescribedBy;
|
|
413
639
|
const onSlashCommandRef = useRef(onSlashCommand);
|
|
@@ -497,6 +723,33 @@ export function CodeEditor({ value, onChange, language = 'text', readOnly = fals
|
|
|
497
723
|
editorViewRef.current = null;
|
|
498
724
|
};
|
|
499
725
|
}, [flushViewState]);
|
|
726
|
+
/**
|
|
727
|
+
* Dismisses the portaled selection toolbar when the user clicks outside the editor and toolbar.
|
|
728
|
+
*/
|
|
729
|
+
useEffect(() => {
|
|
730
|
+
if (!selectionActionToolbar) {
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Closes the toolbar on outside pointer interaction without racing editor blur during selection.
|
|
735
|
+
*/
|
|
736
|
+
const handlePointerDown = (event) => {
|
|
737
|
+
const target = event.target;
|
|
738
|
+
if (!(target instanceof Node)) {
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
const editorRoot = editorViewRef.current?.dom;
|
|
742
|
+
const toolbar = selectionToolbarElementRef.current;
|
|
743
|
+
if (editorRoot?.contains(target) || toolbar?.contains(target)) {
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
setSelectionActionToolbar(null);
|
|
747
|
+
};
|
|
748
|
+
document.addEventListener('pointerdown', handlePointerDown, true);
|
|
749
|
+
return () => {
|
|
750
|
+
document.removeEventListener('pointerdown', handlePointerDown, true);
|
|
751
|
+
};
|
|
752
|
+
}, [selectionActionToolbar]);
|
|
500
753
|
/**
|
|
501
754
|
* Persists wrapper height only after the user finishes a native resize-y drag on the grip.
|
|
502
755
|
* Ignores mount and layout settling so height props do not reconfigure CodeMirror in a loop.
|
|
@@ -613,6 +866,15 @@ export function CodeEditor({ value, onChange, language = 'text', readOnly = fals
|
|
|
613
866
|
isSelectionTooltipOpen: () => selectionTooltipRef.current != null,
|
|
614
867
|
onDismissSelectionTooltip: () => {
|
|
615
868
|
setSelectionTooltipRef.current(null);
|
|
869
|
+
},
|
|
870
|
+
hasSelectionActions,
|
|
871
|
+
selectionActions: selectionActions ?? [],
|
|
872
|
+
onSelectionActionToolbarChange: (state) => {
|
|
873
|
+
setSelectionActionToolbarRef.current(state);
|
|
874
|
+
},
|
|
875
|
+
isSelectionActionToolbarOpen: () => selectionActionToolbarRef.current != null,
|
|
876
|
+
onDismissSelectionActionToolbar: () => {
|
|
877
|
+
setSelectionActionToolbarRef.current(null);
|
|
616
878
|
}
|
|
617
879
|
}), [
|
|
618
880
|
editorThemeExt,
|
|
@@ -623,6 +885,8 @@ export function CodeEditor({ value, onChange, language = 'text', readOnly = fals
|
|
|
623
885
|
language,
|
|
624
886
|
lint,
|
|
625
887
|
hasVariables,
|
|
888
|
+
hasSelectionActions,
|
|
889
|
+
selectionActions,
|
|
626
890
|
tooltipId,
|
|
627
891
|
getVariables,
|
|
628
892
|
getOnEditVariable
|
|
@@ -821,6 +1085,20 @@ export function CodeEditor({ value, onChange, language = 'text', readOnly = fals
|
|
|
821
1085
|
? getVariableTooltipContent(selectionTooltip.key, variables ?? [])
|
|
822
1086
|
: null;
|
|
823
1087
|
const wrapperStyle = height ? { height } : undefined;
|
|
1088
|
+
const activeSelectionActions = selectionActionsRef.current ?? [];
|
|
1089
|
+
const selectionActionToolbarNode = selectionActionToolbar && hasSelectionActions ? (_jsx("div", { ref: selectionToolbarElementRef, role: "toolbar", "aria-label": "Selection actions", className: "hc-code-editor-selection-toolbar app-no-drag pointer-events-auto fixed z-50 flex -translate-x-1/2 -translate-y-full items-center gap-1 bg-transparent p-0 text-[14px] text-text", style: {
|
|
1090
|
+
top: selectionActionToolbar.top - SELECTION_TOOLBAR_OFFSET_PX,
|
|
1091
|
+
left: selectionActionToolbar.left
|
|
1092
|
+
}, children: activeSelectionActions.map((action) => (_jsxs("button", { type: "button", className: "hc-code-editor-selection-action inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-separator bg-control px-2 py-1 text-[14px] text-text shadow-sm hover:bg-surface focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-accent", "aria-label": action.ariaLabel, onMouseDown: (event) => {
|
|
1093
|
+
event.preventDefault();
|
|
1094
|
+
}, onClick: () => {
|
|
1095
|
+
action.onSelect({
|
|
1096
|
+
text: selectionActionToolbar.text,
|
|
1097
|
+
from: selectionActionToolbar.from,
|
|
1098
|
+
to: selectionActionToolbar.to
|
|
1099
|
+
});
|
|
1100
|
+
setSelectionActionToolbar(null);
|
|
1101
|
+
}, children: [action.icon ? _jsx(FaIcon, { icon: action.icon, className: "h-3.5 w-3.5" }) : null, _jsx("span", { children: action.label }), action.shortcutHint ? (_jsx("span", { className: "text-[14px] text-muted", children: action.shortcutHint })) : null] }, action.id))) })) : null;
|
|
824
1102
|
return (_jsxs("div", { ref: wrapperRef, ...props, className: wrapperClassName, style: wrapperStyle, children: [createElement(CodeMirrorImport, {
|
|
825
1103
|
value,
|
|
826
1104
|
onChange: readOnly ? undefined : stableOnChange,
|
|
@@ -837,5 +1115,5 @@ export function CodeEditor({ value, onChange, language = 'text', readOnly = fals
|
|
|
837
1115
|
event.preventDefault();
|
|
838
1116
|
onEditVariable(selectionTooltip.key);
|
|
839
1117
|
setSelectionTooltip(null);
|
|
840
|
-
}, children: "Edit value" })) : null] })) : null] }));
|
|
1118
|
+
}, children: "Edit value" })) : null] })) : null, selectionActionToolbarNode ? portalToBody(selectionActionToolbarNode) : null] }));
|
|
841
1119
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
2
|
import { useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from '@harborclient/sdk/react';
|
|
3
|
+
import { VisibilityMenu } from '../VisibilityMenu/index.js';
|
|
3
4
|
import { segment, segmentGroup } from '../classes.js';
|
|
4
5
|
import { getFocusableElements } from '../useDialogFocus.js';
|
|
5
6
|
import { cn, resolveTabListKeyAction } from '../utils.js';
|
|
6
7
|
import { SegmentedTabsContext } from './SegmentedTabsContext.js';
|
|
7
|
-
import { SegmentedTabsVisibilityMenu } from './SegmentedTabsVisibilityMenu.js';
|
|
8
8
|
export { SegmentedTabsGroup } from './SegmentedTabsGroup.js';
|
|
9
9
|
export { SegmentedTabPanel } from './SegmentedTabPanel.js';
|
|
10
10
|
/**
|
|
@@ -204,5 +204,5 @@ export function SegmentedTabs({ tabs, value: valueProp, onChange: onChangeProp,
|
|
|
204
204
|
'aria-selected': selected,
|
|
205
205
|
...(context ? { 'aria-controls': getPanelId(tab.value) } : {})
|
|
206
206
|
}), children: _jsxs("span", { className: "hc-segmented-tabs-tab-label inline-flex items-center justify-center gap-1.5", children: [_jsx("span", { className: "inline-flex shrink-0 items-center px-1.5", children: _jsx("span", { className: cn('hc-segmented-tabs-tab-indicator h-1.5 w-1.5 shrink-0 rounded-full', tab.indicator ? 'bg-accent' : 'bg-transparent'), "aria-hidden": true }) }), tab.label, _jsx("span", { className: "hc-segmented-tabs-tab-indicator-spacer inline-flex shrink-0 items-center px-1.5", "aria-hidden": true, children: _jsx("span", { className: "h-1.5 w-1.5 shrink-0" }) })] }) }, tab.value));
|
|
207
|
-
}) }), editable && (_jsx(
|
|
207
|
+
}) }), editable && (_jsx(VisibilityMenu, { items: editableTabs, visibleValues: visibleTabValues, onToggle: handleVisibilityToggle }))] }));
|
|
208
208
|
}
|
|
@@ -51,17 +51,21 @@ export interface ToolbarAction {
|
|
|
51
51
|
}
|
|
52
52
|
interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'aria-label'> {
|
|
53
53
|
/**
|
|
54
|
-
* Icon actions rendered in the toolbar.
|
|
54
|
+
* Icon actions rendered left-aligned in the toolbar.
|
|
55
55
|
*/
|
|
56
56
|
actions: ToolbarAction[];
|
|
57
|
+
/**
|
|
58
|
+
* Icon actions rendered right-aligned in the toolbar (e.g. toggles).
|
|
59
|
+
*/
|
|
60
|
+
toggles?: ToolbarAction[];
|
|
57
61
|
/**
|
|
58
62
|
* Accessible name for the toolbar landmark.
|
|
59
63
|
*/
|
|
60
64
|
ariaLabel?: string;
|
|
61
65
|
}
|
|
62
66
|
/**
|
|
63
|
-
* Top-of-sidebar toolbar with left-aligned
|
|
67
|
+
* Top-of-sidebar toolbar with left-aligned actions and optional right-aligned toggles.
|
|
64
68
|
*/
|
|
65
|
-
export declare function Toolbar({ actions, ariaLabel, className, ...props }: Props): JSX.Element;
|
|
69
|
+
export declare function Toolbar({ actions, toggles, ariaLabel, className, ...props }: Props): JSX.Element;
|
|
66
70
|
export {};
|
|
67
71
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Toolbar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIjG;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAE/C;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACjD;AAED,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACtF;;OAEG;IACH,OAAO,EAAE,aAAa,EAAE,CAAC;IAEzB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Toolbar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIjG;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAE/C;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACjD;AAED,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACtF;;OAEG;IACH,OAAO,EAAE,aAAa,EAAE,CAAC;IAEzB;;OAEG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAE1B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsDD;;GAEG;AACH,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,OAAO,EACP,SAAqB,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAqBrB"}
|
|
@@ -3,14 +3,28 @@ import { FaIcon } from '../FaIcon/index.js';
|
|
|
3
3
|
import { cn } from '../utils.js';
|
|
4
4
|
/**
|
|
5
5
|
* Tailwind classes for toolbar icon action buttons.
|
|
6
|
+
*
|
|
7
|
+
* @param pressed - Whether the action is in a pressed/toggled-on state.
|
|
8
|
+
* @returns Class string for the action button.
|
|
6
9
|
*/
|
|
7
|
-
|
|
10
|
+
function toolbarActionButtonClasses(pressed) {
|
|
11
|
+
return cn('hc-toolbar-action app-no-drag inline-flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-md border-none text-text', pressed
|
|
12
|
+
? 'bg-selection'
|
|
13
|
+
: 'bg-transparent hover:bg-selection focus-visible:bg-selection focus-visible:text-text', 'disabled:cursor-not-allowed disabled:opacity-50');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Renders a single toolbar icon action with optional popover content.
|
|
17
|
+
*
|
|
18
|
+
* @param action - Declarative action to render as an icon button.
|
|
19
|
+
* @returns Toolbar action button wrapped with optional popover anchor.
|
|
20
|
+
*/
|
|
21
|
+
function renderAction(action) {
|
|
22
|
+
const title = action.title ?? action.label;
|
|
23
|
+
return (_jsxs("div", { className: "hc-toolbar-action-wrap relative", children: [_jsx("button", { type: "button", ref: action.buttonRef, className: toolbarActionButtonClasses(action.ariaPressed === true), title: title, "aria-label": action.label, "aria-expanded": action.ariaExpanded, "aria-pressed": action.ariaPressed, "aria-haspopup": action.ariaHaspopup, disabled: action.disabled, onClick: action.onClick, children: _jsx(FaIcon, { icon: action.icon, className: cn('hc-toolbar-action-icon h-5! w-5!', action.ariaPressed === true ? 'opacity-100' : 'opacity-50') }) }), action.popover] }, action.id));
|
|
24
|
+
}
|
|
8
25
|
/**
|
|
9
|
-
* Top-of-sidebar toolbar with left-aligned
|
|
26
|
+
* Top-of-sidebar toolbar with left-aligned actions and optional right-aligned toggles.
|
|
10
27
|
*/
|
|
11
|
-
export function Toolbar({ actions, ariaLabel = 'Toolbar', className, ...props }) {
|
|
12
|
-
return (
|
|
13
|
-
const title = action.title ?? action.label;
|
|
14
|
-
return (_jsxs("div", { className: "hc-toolbar-action-wrap relative", children: [_jsx("button", { type: "button", ref: action.buttonRef, className: TOOLBAR_ACTION_BUTTON, title: title, "aria-label": action.label, "aria-expanded": action.ariaExpanded, "aria-pressed": action.ariaPressed, "aria-haspopup": action.ariaHaspopup, disabled: action.disabled, onClick: action.onClick, children: _jsx(FaIcon, { icon: action.icon, className: cn('hc-toolbar-action-icon h-5! w-5!', action.ariaPressed === true ? 'opacity-100' : 'opacity-50') }) }), action.popover] }, action.id));
|
|
15
|
-
}) }) }));
|
|
28
|
+
export function Toolbar({ actions, toggles, ariaLabel = 'Toolbar', className, ...props }) {
|
|
29
|
+
return (_jsxs("div", { ...props, role: "toolbar", "aria-label": ariaLabel, className: cn('hc-toolbar app-no-drag flex shrink-0 items-center border-b border-separator bg-sidebar-toolbar px-2 py-2', className), children: [_jsx("div", { className: "hc-toolbar-actions flex items-center gap-1 leading-none", children: actions.map(renderAction) }), toggles && toggles.length > 0 ? (_jsx("div", { className: "hc-toolbar-toggles ml-auto flex items-center gap-1", children: toggles.map(renderAction) })) : null] }));
|
|
16
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/VariableInput/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AACtF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/VariableInput/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AACtF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAqBnE,MAAM,WAAW,KAAM,SAAQ,IAAI,CACjC,wBAAwB,CAAC,KAAK,CAAC,EAC/B,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,YAAY,GAAG,iBAAiB,GAAG,WAAW,GAAG,UAAU,CAC9F;IACC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,SAAS,EAAE,QAAQ,EAAE,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAc,EACd,gBAAgB,EAChB,cAAc,EACd,EAAE,EACF,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,MAAM,EACN,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAgVrB"}
|
|
@@ -7,6 +7,10 @@ import { Button } from '../Button/index.js';
|
|
|
7
7
|
import { VariableTooltipValue } from '../VariableTooltip/index.js';
|
|
8
8
|
import { Input } from '../forms/index.js';
|
|
9
9
|
import { cn } from '../utils.js';
|
|
10
|
+
/** Delay after the pointer stops moving before a hover tooltip is shown. */
|
|
11
|
+
const TOOLTIP_SHOW_DELAY_MS = 500;
|
|
12
|
+
/** Grace period before hiding so the pointer can reach the tooltip. */
|
|
13
|
+
const TOOLTIP_HIDE_DELAY_MS = 400;
|
|
10
14
|
/**
|
|
11
15
|
* Text input that highlights {{variable}} tokens and shows resolved values on hover.
|
|
12
16
|
*
|
|
@@ -19,6 +23,7 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
19
23
|
const backdropRef = useRef(null);
|
|
20
24
|
const spanRefs = useRef(new Map());
|
|
21
25
|
const hideTimer = useRef(null);
|
|
26
|
+
const showTimer = useRef(null);
|
|
22
27
|
const [tooltip, setTooltip] = useState(null);
|
|
23
28
|
const tooltipId = useId();
|
|
24
29
|
const { open: autocompleteOpen, items: autocompleteItems, activeIndex: autocompleteActiveIndex, listboxId, onFocus: openAutocomplete, onBlur: closeAutocomplete, onInputKeyDown, selectItem, setActiveIndex, closeSuggestions } = useAutocomplete({
|
|
@@ -45,20 +50,15 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
45
50
|
*/
|
|
46
51
|
const scheduleHide = () => {
|
|
47
52
|
cancelHide();
|
|
48
|
-
hideTimer.current = window.setTimeout(() => setTooltip(null),
|
|
53
|
+
hideTimer.current = window.setTimeout(() => setTooltip(null), TOOLTIP_HIDE_DELAY_MS);
|
|
49
54
|
};
|
|
50
55
|
/**
|
|
51
|
-
* Clears any pending tooltip
|
|
56
|
+
* Clears any pending tooltip show timer.
|
|
52
57
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const syncScroll = () => {
|
|
58
|
-
const input = inputRef.current;
|
|
59
|
-
const backdrop = backdropRef.current;
|
|
60
|
-
if (input && backdrop) {
|
|
61
|
-
backdrop.scrollLeft = input.scrollLeft;
|
|
58
|
+
const cancelShow = () => {
|
|
59
|
+
if (showTimer.current != null) {
|
|
60
|
+
window.clearTimeout(showTimer.current);
|
|
61
|
+
showTimer.current = null;
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
/**
|
|
@@ -73,6 +73,37 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
73
73
|
left
|
|
74
74
|
});
|
|
75
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* Shows the tooltip once the pointer has stopped moving for {@link TOOLTIP_SHOW_DELAY_MS}.
|
|
78
|
+
*
|
|
79
|
+
* @param key - Variable name from the hovered {{key}} token.
|
|
80
|
+
* @param top - Screen Y coordinate for tooltip placement.
|
|
81
|
+
* @param left - Screen X coordinate for tooltip placement.
|
|
82
|
+
*/
|
|
83
|
+
const scheduleShow = (key, top, left) => {
|
|
84
|
+
cancelShow();
|
|
85
|
+
showTimer.current = window.setTimeout(() => {
|
|
86
|
+
showTimer.current = null;
|
|
87
|
+
showTooltipForKey(key, top, left);
|
|
88
|
+
}, TOOLTIP_SHOW_DELAY_MS);
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Clears pending tooltip timers when the component unmounts.
|
|
92
|
+
*/
|
|
93
|
+
useEffect(() => () => {
|
|
94
|
+
cancelHide();
|
|
95
|
+
cancelShow();
|
|
96
|
+
}, []);
|
|
97
|
+
/**
|
|
98
|
+
* Keeps the colored backdrop aligned with horizontal scroll in the input.
|
|
99
|
+
*/
|
|
100
|
+
const syncScroll = () => {
|
|
101
|
+
const input = inputRef.current;
|
|
102
|
+
const backdrop = backdropRef.current;
|
|
103
|
+
if (input && backdrop) {
|
|
104
|
+
backdrop.scrollLeft = input.scrollLeft;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
76
107
|
/**
|
|
77
108
|
* Updates the tooltip based on the current text caret position.
|
|
78
109
|
*/
|
|
@@ -105,7 +136,7 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
105
136
|
showTooltipForKey(match.key, rect.top, rect.left + rect.width / 2);
|
|
106
137
|
};
|
|
107
138
|
/**
|
|
108
|
-
* Shows a tooltip when the pointer
|
|
139
|
+
* Shows a tooltip when the pointer rests over a variable token span.
|
|
109
140
|
*/
|
|
110
141
|
const handleMouseMove = (e) => {
|
|
111
142
|
cancelHide();
|
|
@@ -120,10 +151,18 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
120
151
|
e.clientX <= rect.right &&
|
|
121
152
|
e.clientY >= rect.top &&
|
|
122
153
|
e.clientY <= rect.bottom) {
|
|
123
|
-
|
|
154
|
+
scheduleShow(token.key, rect.top, rect.left + rect.width / 2);
|
|
124
155
|
return;
|
|
125
156
|
}
|
|
126
157
|
}
|
|
158
|
+
cancelShow();
|
|
159
|
+
scheduleHide();
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Cancels a pending show and hides the tooltip when the pointer leaves the input.
|
|
163
|
+
*/
|
|
164
|
+
const handleMouseLeave = () => {
|
|
165
|
+
cancelShow();
|
|
127
166
|
scheduleHide();
|
|
128
167
|
};
|
|
129
168
|
/**
|
|
@@ -167,7 +206,7 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
167
206
|
}, onFocus: () => {
|
|
168
207
|
openAutocomplete();
|
|
169
208
|
updateTooltipFromCaret();
|
|
170
|
-
}, onBlur: closeAutocomplete, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onSelect: updateTooltipFromCaret, onClick: updateTooltipFromCaret, onScroll: syncScroll, onMouseMove: handleMouseMove, onMouseLeave:
|
|
209
|
+
}, onBlur: closeAutocomplete, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onSelect: updateTooltipFromCaret, onClick: updateTooltipFromCaret, onScroll: syncScroll, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave }), source && (_jsx(SuggestionList, { open: autocompleteOpen, items: autocompleteItems, activeIndex: autocompleteActiveIndex, anchorRef: inputRef, listboxId: listboxId, onSelect: selectItem, onActiveIndexChange: setActiveIndex, onClose: closeSuggestions })), tooltip && tooltipContent && (_jsxs("div", { id: tooltipId, role: "tooltip", className: "hc-variable-input-tooltip pointer-events-auto fixed z-50 flex max-w-sm -translate-x-1/2 -translate-y-full flex-col gap-2 rounded-lg border border-separator bg-surface px-4 py-3 text-[16px] text-text shadow-md after:pointer-events-auto after:absolute after:right-0 after:-bottom-2 after:left-0 after:h-2 after:content-['']", style: { top: tooltip.top - 4, left: tooltip.left }, onMouseEnter: cancelHide, onMouseLeave: scheduleHide, children: [_jsx(VariableTooltipValue, { value: tooltipContent.text, variableKey: tooltip.key, muted: tooltipContent.muted }), onEditVariable && (_jsx(Button, { variant: "secondary", className: "hc-variable-input-tooltip-edit self-start", "aria-label": `Edit value for ${tooltip.key}`, onClick: () => {
|
|
171
210
|
onEditVariable(tooltip.key);
|
|
172
211
|
setTooltip(null);
|
|
173
212
|
}, children: "Edit value" }))] }))] }));
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { JSX, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* One entry in a {@link VisibilityMenu} that can be shown or hidden.
|
|
4
|
+
*/
|
|
5
|
+
export interface VisibilityMenuItem<T extends string> {
|
|
6
|
+
/**
|
|
7
|
+
* Unique item identifier.
|
|
8
|
+
*/
|
|
9
|
+
value: T;
|
|
10
|
+
/**
|
|
11
|
+
* Item label or custom content.
|
|
12
|
+
*/
|
|
13
|
+
label: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
interface Props<T extends string> {
|
|
16
|
+
/**
|
|
17
|
+
* Items that can be shown or hidden via the menu.
|
|
18
|
+
*/
|
|
19
|
+
items: VisibilityMenuItem<T>[];
|
|
20
|
+
/**
|
|
21
|
+
* Item values currently visible in the parent UI.
|
|
22
|
+
*/
|
|
23
|
+
visibleValues: T[];
|
|
24
|
+
/**
|
|
25
|
+
* Called when the user toggles an item's visibility in the menu.
|
|
26
|
+
*/
|
|
27
|
+
onToggle: (value: T) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Caret-triggered menu for toggling which items are visible in a parent control.
|
|
31
|
+
*/
|
|
32
|
+
export declare function VisibilityMenu<T extends string>({ items, visibleValues, onToggle }: Props<T>): JSX.Element;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/VisibilityMenu/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAK3D;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM;IAClD;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;IAC9B;;OAEG;IACH,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/B;;OAEG;IACH,aAAa,EAAE,CAAC,EAAE,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC9B;AAQD;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,EAC/C,KAAK,EACL,aAAa,EACb,QAAQ,EACT,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAgLxB"}
|
package/dist/components/{SegmentedTabs/SegmentedTabsVisibilityMenu.js → VisibilityMenu/index.js}
RENAMED
|
@@ -7,9 +7,9 @@ import { cn, resolveTabListKeyAction } from '../utils.js';
|
|
|
7
7
|
const menuItemClass = 'flex w-full cursor-pointer items-center gap-2 border-none bg-transparent px-3.5 py-1.5 text-left text-[14px] text-text hover:bg-selection app-no-drag';
|
|
8
8
|
const triggerClassName = '!rounded-full hover:!bg-[rgba(0,122,255,0.18)] dark:hover:!bg-[rgba(10,132,255,0.22)]';
|
|
9
9
|
/**
|
|
10
|
-
* Caret-triggered menu for toggling which
|
|
10
|
+
* Caret-triggered menu for toggling which items are visible in a parent control.
|
|
11
11
|
*/
|
|
12
|
-
export function
|
|
12
|
+
export function VisibilityMenu({ items, visibleValues, onToggle }) {
|
|
13
13
|
const menuId = useId();
|
|
14
14
|
const menuElementId = `${menuId}-menu`;
|
|
15
15
|
const rootRef = useRef(null);
|
|
@@ -18,7 +18,7 @@ export function SegmentedTabsVisibilityMenu({ tabs, visibleTabValues, onToggle }
|
|
|
18
18
|
const wasOpenRef = useRef(false);
|
|
19
19
|
const [isOpen, setIsOpen] = useState(false);
|
|
20
20
|
const [focusedIndex, setFocusedIndex] = useState(0);
|
|
21
|
-
const visibleSet = new Set(
|
|
21
|
+
const visibleSet = new Set(visibleValues);
|
|
22
22
|
/**
|
|
23
23
|
* Closes the menu and returns focus to the trigger button.
|
|
24
24
|
*/
|
|
@@ -32,11 +32,11 @@ export function SegmentedTabsVisibilityMenu({ tabs, visibleTabValues, onToggle }
|
|
|
32
32
|
* Opens the menu and focuses the first or last item.
|
|
33
33
|
*/
|
|
34
34
|
const openMenu = useCallback((focusLast = false) => {
|
|
35
|
-
if (
|
|
35
|
+
if (items.length === 0)
|
|
36
36
|
return;
|
|
37
|
-
setFocusedIndex(focusLast ?
|
|
37
|
+
setFocusedIndex(focusLast ? items.length - 1 : 0);
|
|
38
38
|
setIsOpen(true);
|
|
39
|
-
}, [
|
|
39
|
+
}, [items.length]);
|
|
40
40
|
/**
|
|
41
41
|
* Focuses a menu item by index and updates roving tabindex state.
|
|
42
42
|
*/
|
|
@@ -110,38 +110,38 @@ export function SegmentedTabsVisibilityMenu({ tabs, visibleTabValues, onToggle }
|
|
|
110
110
|
* Handles keyboard navigation within the open menu.
|
|
111
111
|
*/
|
|
112
112
|
const handleMenuKeyDown = (event) => {
|
|
113
|
-
if (
|
|
113
|
+
if (items.length === 0)
|
|
114
114
|
return;
|
|
115
115
|
if (event.key === 'Tab') {
|
|
116
116
|
closeMenu();
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
|
-
const arrowIndex = resolveTabListKeyAction(event.key, focusedIndex,
|
|
119
|
+
const arrowIndex = resolveTabListKeyAction(event.key, focusedIndex, items.length);
|
|
120
120
|
if (arrowIndex !== null) {
|
|
121
121
|
event.preventDefault();
|
|
122
122
|
focusItem(arrowIndex);
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
|
-
return (_jsxs("div", { ref: rootRef, className: "hc-
|
|
125
|
+
return (_jsxs("div", { ref: rootRef, className: "hc-visibility-menu relative shrink-0", children: [_jsx(Button, { innerRef: triggerRef, type: "button", variant: "icon", className: cn('hc-visibility-menu-trigger', triggerClassName), "aria-label": "Customize visible tabs", "aria-haspopup": "menu", "aria-expanded": isOpen, "aria-controls": isOpen ? menuElementId : undefined, onClick: () => {
|
|
126
126
|
if (isOpen) {
|
|
127
127
|
closeMenu();
|
|
128
128
|
}
|
|
129
129
|
else {
|
|
130
130
|
openMenu(false);
|
|
131
131
|
}
|
|
132
|
-
}, onKeyDown: handleTriggerKeyDown, children: _jsx(FaIcon, { icon: faCaretDown, className: "h-3.5 w-3.5" }) }), isOpen && (_jsx("div", { id: menuElementId, role: "menu", className: "hc-
|
|
133
|
-
const checked = visibleSet.has(
|
|
132
|
+
}, onKeyDown: handleTriggerKeyDown, children: _jsx(FaIcon, { icon: faCaretDown, className: "h-3.5 w-3.5" }) }), isOpen && (_jsx("div", { id: menuElementId, role: "menu", className: "hc-visibility-menu-panel app-no-drag absolute top-full right-0 z-10 mt-0.5 min-w-[140px] rounded-md border border-separator bg-surface py-1 shadow-md", onKeyDown: handleMenuKeyDown, children: items.map((item, index) => {
|
|
133
|
+
const checked = visibleSet.has(item.value);
|
|
134
134
|
return (_jsx(MenuCheckboxItem, { ref: (element) => {
|
|
135
135
|
itemRefs.current[index] = element;
|
|
136
|
-
}, checked: checked, tabIndex: index === focusedIndex ? 0 : -1, label:
|
|
136
|
+
}, checked: checked, tabIndex: index === focusedIndex ? 0 : -1, label: item.label, onSelect: () => onToggle(item.value) }, item.value));
|
|
137
137
|
}) }))] }));
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
|
-
* Single checkbox-style row in the
|
|
140
|
+
* Single checkbox-style row in the visibility menu.
|
|
141
141
|
*/
|
|
142
142
|
function MenuCheckboxItem({ checked, label, tabIndex, onSelect, ref }) {
|
|
143
|
-
return (_jsxs("button", { ref: ref, type: "button", role: "menuitemcheckbox", "aria-checked": checked, tabIndex: tabIndex, className: cn('hc-
|
|
143
|
+
return (_jsxs("button", { ref: ref, type: "button", role: "menuitemcheckbox", "aria-checked": checked, tabIndex: tabIndex, className: cn('hc-visibility-menu-item', menuItemClass), onClick: (e) => {
|
|
144
144
|
e.stopPropagation();
|
|
145
145
|
onSelect();
|
|
146
|
-
}, children: [_jsx("span", { className: "hc-
|
|
146
|
+
}, children: [_jsx("span", { className: "hc-visibility-menu-item-check inline-flex w-4 shrink-0 justify-center", "aria-hidden": true, children: checked ? _jsx(FaIcon, { icon: faCheck, className: "h-3 w-3" }) : null }), _jsx("span", { className: "hc-visibility-menu-item-label min-w-0", children: label })] }));
|
|
147
147
|
}
|
|
@@ -10,7 +10,7 @@ export { Button } from './Button/index.js';
|
|
|
10
10
|
export { CodeEditor, CODE_EDITOR_THEME_OPTIONS } from './CodeEditor/index.js';
|
|
11
11
|
export { CodeEditorConfigProvider, useCodeEditorConfig, DEFAULT_CODE_EDITOR_CONFIG } from './CodeEditor/config.js';
|
|
12
12
|
export type { CodeEditorConfig } from './CodeEditor/config.js';
|
|
13
|
-
export type { Props as CodeEditorProps, CodeEditorLanguage, CodeEditorSelectionRange, CodeEditorSlashCommand, CodeEditorSlashCoords, CodeEditorSlashTrigger, CodeEditorViewState } from './CodeEditor/index.js';
|
|
13
|
+
export type { Props as CodeEditorProps, CodeEditorLanguage, CodeEditorSelectionAction, CodeEditorSelectionRange, CodeEditorSlashCommand, CodeEditorSlashCoords, CodeEditorSlashTrigger, CodeEditorTextSelection, CodeEditorViewState } from './CodeEditor/index.js';
|
|
14
14
|
export { EmptyState } from './EmptyState/index.js';
|
|
15
15
|
export { FaIcon } from './FaIcon/index.js';
|
|
16
16
|
export { FieldError } from './FieldError/index.js';
|
|
@@ -54,6 +54,8 @@ export { VariableInput } from './VariableInput/index.js';
|
|
|
54
54
|
export type { Props as VariableInputProps } from './VariableInput/index.js';
|
|
55
55
|
export { VariableTable } from './VariableTable/index.js';
|
|
56
56
|
export { VariableTooltipValue, appendVariableTooltipValueRow, buildVariableTooltipDom } from './VariableTooltip/index.js';
|
|
57
|
+
export { VisibilityMenu } from './VisibilityMenu/index.js';
|
|
58
|
+
export type { VisibilityMenuItem } from './VisibilityMenu/index.js';
|
|
57
59
|
export { cleanVariables, resolveTabListKeyAction } from './utils.js';
|
|
58
60
|
export type { TabListKeyOptions } from './utils.js';
|
|
59
61
|
export { useDialogFocus, getFocusableElements } from './useDialogFocus.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACvF,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,KAAK,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EACV,KAAK,IAAI,eAAe,EACxB,kBAAkB,EAClB,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,KAAK,IAAI,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EACL,KAAK,EACL,QAAQ,EACR,KAAK,EACL,MAAM,EACN,QAAQ,EACR,KAAK,EACL,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,KAAK,IAAI,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC7E,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACL,cAAc,EACd,UAAU,EACV,oBAAoB,EACpB,+BAA+B,EAC/B,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChG,YAAY,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,KAAK,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -40,6 +40,7 @@ export { Table, TableBody, TableCell, TableHead, TableHeader, tableCellClass, ta
|
|
|
40
40
|
export { VariableInput } from './VariableInput/index.js';
|
|
41
41
|
export { VariableTable } from './VariableTable/index.js';
|
|
42
42
|
export { VariableTooltipValue, appendVariableTooltipValueRow, buildVariableTooltipDom } from './VariableTooltip/index.js';
|
|
43
|
+
export { VisibilityMenu } from './VisibilityMenu/index.js';
|
|
43
44
|
export { cleanVariables, resolveTabListKeyAction } from './utils.js';
|
|
44
45
|
export { useDialogFocus, getFocusableElements } from './useDialogFocus.js';
|
|
45
46
|
export { segment, segmentGroup } from './classes.js';
|
package/package.json
CHANGED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { JSX } from 'react';
|
|
2
|
-
import type { TabItem } from './types.js';
|
|
3
|
-
interface Props<T extends string> {
|
|
4
|
-
/**
|
|
5
|
-
* Tabs that can be shown or hidden via the menu.
|
|
6
|
-
*/
|
|
7
|
-
tabs: TabItem<T>[];
|
|
8
|
-
/**
|
|
9
|
-
* Tab values currently shown in the tab strip.
|
|
10
|
-
*/
|
|
11
|
-
visibleTabValues: T[];
|
|
12
|
-
/**
|
|
13
|
-
* Called when the user toggles a tab's visibility in the menu.
|
|
14
|
-
*/
|
|
15
|
-
onToggle: (tabValue: T) => void;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Caret-triggered menu for toggling which segmented tabs are visible.
|
|
19
|
-
*/
|
|
20
|
-
export declare function SegmentedTabsVisibilityMenu<T extends string>({ tabs, visibleTabValues, onToggle }: Props<T>): JSX.Element;
|
|
21
|
-
export {};
|
|
22
|
-
//# sourceMappingURL=SegmentedTabsVisibilityMenu.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentedTabsVisibilityMenu.d.ts","sourceRoot":"","sources":["../../../src/components/SegmentedTabs/SegmentedTabsVisibilityMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAA4B,MAAM,OAAO,CAAC;AAI3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;IAC9B;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnB;;OAEG;IACH,gBAAgB,EAAE,CAAC,EAAE,CAAC;IAEtB;;OAEG;IACH,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;CACjC;AAQD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,MAAM,EAAE,EAC5D,IAAI,EACJ,gBAAgB,EAChB,QAAQ,EACT,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAgLxB"}
|