Files
zeekay c01baee974 the face is Zen, and it ships from @hanzo/font
One family. Font stacks name Zen and fall back to the native faces, tokens
name the role rather than a face, and the packages that used to supply a
face now point at @hanzo/font.

Self-hosted @font-face blocks are removed rather than renamed: rewriting the
family in one would leave a src pointing at a file this repo no longer ships.
@hanzo/font carries the binaries and declares the faces, so the local copies
go with the declaration that used them.

Comments naming a face we no longer use are deleted, not reworded.
2026-09-01 14:21:32 -07:00

80 lines
2.5 KiB
TypeScript

import {keyframes} from '@emotion/react';
import styled from '@emotion/styled';
import ExternalLink from 'sentry/components/links/externalLink';
import SentryAppComponentIcon from 'sentry/components/sentryAppComponentIcon';
import {Tooltip} from 'sentry/components/tooltip';
import {space} from 'sentry/styles/space';
import type {SentryAppComponent, SentryAppSchemaStacktraceLink} from 'sentry/types';
import {addQueryParamsToExistingUrl} from 'sentry/utils/queryString';
import {recordInteraction} from 'sentry/utils/recordSentryAppInteraction';
type Props = {
components: SentryAppComponent<SentryAppSchemaStacktraceLink>[];
filename: string;
lineNo: number | null;
};
function OpenInContextLine({lineNo, filename, components}: Props) {
const handleRecordInteraction =
(slug: SentryAppComponent<SentryAppSchemaStacktraceLink>['sentryApp']['slug']) =>
() => {
recordInteraction(slug, 'sentry_app_component_interacted', {
componentType: 'stacktrace-link',
});
};
const getUrl = (url: SentryAppSchemaStacktraceLink['url']) => {
return addQueryParamsToExistingUrl(url, {lineNo, filename});
};
return (
<OpenInContainer>
{components.map(component => {
const url = getUrl(component.schema.url);
const {slug} = component.sentryApp;
const onClickRecordInteraction = handleRecordInteraction(slug);
return (
<Tooltip key={component.uuid} title={component.sentryApp.name} skipWrapper>
<OpenInLink
aria-label={component.sentryApp.name}
href={url}
onClick={onClickRecordInteraction}
onContextMenu={onClickRecordInteraction}
openInNewTab
>
<SentryAppComponentIcon sentryAppComponent={component} size={16} />
</OpenInLink>
</Tooltip>
);
})}
</OpenInContainer>
);
}
export {OpenInContextLine};
const fadeIn = keyframes`
from { opacity: 0; }
to { opacity: 1; }
`;
const OpenInContainer = styled('div')`
display: flex;
gap: ${space(1)};
align-items: center;
z-index: 1;
font-family: Zen, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif{p => p.theme.text.family};
text-indent: initial;
overflow: auto;
white-space: nowrap;
animation: ${fadeIn} 0.2s ease-in-out forwards;
`;
const OpenInLink = styled(ExternalLink)`
display: flex;
gap: ${space(0.75)};
align-items: center;
color: ${p => p.theme.gray300};
`;