Skip to content

Commit b6bcd76

Browse files
committed
Add an easy-copy context menu to headers
1 parent 56ca614 commit b6bcd76

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

src/components/view/http/header-details.tsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ import { inject, observer } from 'mobx-react';
55
import { styled } from '../../../styles';
66
import { RawHeaders } from '../../../types';
77
import { Icon } from '../../../icons';
8+
import { copyToClipboard } from '../../../util/ui';
89

910
import { getHeaderDocs } from '../../../model/http/http-docs';
1011
import { AccountStore } from '../../../model/account/account-store';
12+
import { UiStore } from '../../../model/ui/ui-store';
13+
import { ContextMenuItem } from '../../../model/ui/context-menu';
1114

1215
import { CollapsibleSection } from '../../common/collapsible-section';
1316
import { DocsLink } from '../../common/docs-link';
@@ -40,22 +43,43 @@ const HeaderKeyValueContainer = styled(CollapsibleSectionSummary)`
4043

4144
const LONG_HEADER_LIMIT = 500;
4245

43-
const HeaderKeyValue = (p: {
46+
const HEADER_CONTEXT_MENU = [
47+
{ type: 'option', label: 'Copy header value', callback: ({ value }) => copyToClipboard(value) },
48+
{ type: 'option', label: 'Copy header name', callback: ({ key }) => copyToClipboard(key) },
49+
{ type: 'option', label: 'Copy header as "name: value"', callback: ({ key, value }) => copyToClipboard(`${key}: ${value}`) },
50+
] satisfies Array<ContextMenuItem<{ key: string, value: string }>>;
51+
52+
const HeaderKeyValue = inject('uiStore')((p: {
4453
headerKey: string,
4554
headerValue: string,
4655

4756
// All injected by CollapsibleSection itself:
4857
children?: React.ReactNode,
4958
open?: boolean,
50-
withinGrid?: boolean
59+
withinGrid?: boolean,
60+
61+
uiStore?: UiStore
5162
}) => {
5263
const isLongValue = p.headerValue.length > LONG_HEADER_LIMIT;
5364
const [isExpanded, setExpanded] = React.useState(false);
5465

5566
const expand = React.useCallback(() => setExpanded(true), [setExpanded]);
5667
const collapse = React.useCallback(() => setExpanded(false), [setExpanded]);
5768

58-
return <HeaderKeyValueContainer open={p.open} withinGrid={p.withinGrid}>
69+
const onContextMenu = React.useCallback((e: React.MouseEvent) => {
70+
if (window.getSelection()?.type === 'Range') return; // If you right click selected text, we delegate to defaults
71+
72+
p.uiStore!.handleContextMenuEvent(e, HEADER_CONTEXT_MENU, {
73+
key: p.headerKey,
74+
value: p.headerValue
75+
});
76+
}, [p.uiStore, p.headerKey, p.headerValue]);
77+
78+
return <HeaderKeyValueContainer
79+
open={p.open}
80+
withinGrid={p.withinGrid}
81+
onContextMenu={onContextMenu}
82+
>
5983
{ p.children }
6084
<HeaderName>{ p.headerKey }: </HeaderName>
6185
{ !isLongValue
@@ -80,7 +104,7 @@ const HeaderKeyValue = (p: {
80104
</LongHeaderValue>
81105
}
82106
</HeaderKeyValueContainer>;
83-
};
107+
});
84108

85109
const LongHeaderValue = styled.span`
86110
position: relative;

0 commit comments

Comments
 (0)