value.tsx 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import {useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import {AnnotatedText} from 'sentry/components/events/meta/annotatedText';
  4. import {Tooltip} from 'sentry/components/tooltip';
  5. import {IconSliders} from 'sentry/icons';
  6. import {t} from 'sentry/locale';
  7. import {space} from 'sentry/styles/space';
  8. import {Meta} from 'sentry/types';
  9. const REGISTER_VIEWS = [t('Hexadecimal'), t('Numeric')];
  10. type Props = {
  11. value: string | number;
  12. meta?: Meta;
  13. };
  14. type State = {
  15. view: number;
  16. };
  17. export function FrameRegisterValue({meta, value}: Props) {
  18. const [state, setState] = useState<State>({view: 0});
  19. function formatValue() {
  20. try {
  21. const parsed = typeof value === 'string' ? parseInt(value, 16) : value;
  22. if (isNaN(parsed)) {
  23. return value;
  24. }
  25. switch (state.view) {
  26. case 1:
  27. return `${parsed}`;
  28. case 0:
  29. default:
  30. return `0x${parsed.toString(16).padStart(16, '0')}`;
  31. }
  32. } catch {
  33. return value;
  34. }
  35. }
  36. return (
  37. <InlinePre>
  38. <AnnotatedText value={formatValue()} meta={meta} />
  39. <StyledTooltip
  40. title={REGISTER_VIEWS[state.view]}
  41. containerDisplayMode="inline-flex"
  42. >
  43. <Toggle
  44. onClick={() => {
  45. setState({view: (state.view + 1) % REGISTER_VIEWS.length});
  46. }}
  47. size="xs"
  48. aria-label={t('Toggle register value format')}
  49. />
  50. </StyledTooltip>
  51. </InlinePre>
  52. );
  53. }
  54. const StyledTooltip = styled(Tooltip)`
  55. align-items: center;
  56. `;
  57. const InlinePre = styled('pre')`
  58. margin: 0;
  59. padding: ${space(1)};
  60. display: inline-grid;
  61. line-height: 1rem;
  62. grid-template-columns: 1fr max-content;
  63. gap: ${space(1)};
  64. text-align: left;
  65. font-size: ${p => p.theme.fontSizeSmall};
  66. `;
  67. const Toggle = styled(IconSliders)`
  68. opacity: 0.33;
  69. cursor: pointer;
  70. &:hover {
  71. opacity: 1;
  72. }
  73. `;