global.tsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. import type {Theme} from '@emotion/react';
  2. import {css, Global} from '@emotion/react';
  3. import {space} from 'sentry/styles/space';
  4. const prismStyles = (theme: Theme) => css`
  5. :root {
  6. ${theme.prismVariables};
  7. }
  8. /* Use dark Prism theme for code snippets imported from Sentry Docs */
  9. .gatsby-highlight,
  10. .prism-dark {
  11. ${theme.prismDarkVariables};
  12. }
  13. pre[class*='language-'] {
  14. overflow-x: auto;
  15. padding: ${space(1)} ${space(2)};
  16. border-radius: ${theme.borderRadius};
  17. box-shadow: none;
  18. code {
  19. background: unset;
  20. }
  21. }
  22. pre[class*='language-'],
  23. code[class*='language-'] {
  24. color: var(--prism-base);
  25. background: var(--prism-block-background);
  26. font-size: ${theme.codeFontSize};
  27. text-shadow: none;
  28. font-family: ${theme.text.familyMono};
  29. direction: ltr;
  30. text-align: left;
  31. white-space: pre;
  32. word-spacing: normal;
  33. word-break: normal;
  34. -moz-tab-size: 4;
  35. -o-tab-size: 4;
  36. tab-size: 4;
  37. -webkit-hyphens: none;
  38. -moz-hyphens: none;
  39. -ms-hyphens: none;
  40. hyphens: none;
  41. .namespace {
  42. opacity: 0.7;
  43. }
  44. .token.comment,
  45. .token.prolog,
  46. .token.doctype,
  47. .token.cdata {
  48. color: var(--prism-comment);
  49. }
  50. .token.punctuation {
  51. color: var(--prism-punctuation);
  52. }
  53. .token.property,
  54. .token.tag,
  55. .token.boolean,
  56. .token.number,
  57. .token.constant,
  58. .token.symbol,
  59. .token.deleted {
  60. color: var(--prism-property);
  61. }
  62. .token.selector,
  63. .token.attr-name,
  64. .token.string,
  65. .token.char,
  66. .token.builtin,
  67. .token.inserted {
  68. color: var(--prism-selector);
  69. }
  70. .token.operator,
  71. .token.entity,
  72. .token.url,
  73. .language-css .token.string,
  74. .style .token.string {
  75. color: var(--prism-operator);
  76. background: none;
  77. }
  78. .token.atrule,
  79. .token.attr-value,
  80. .token.keyword {
  81. color: var(--prism-keyword);
  82. }
  83. .token.function {
  84. color: var(--prism-function);
  85. }
  86. .token.regex,
  87. .token.important,
  88. .token.variable {
  89. color: var(--prism-variable);
  90. }
  91. .token.important,
  92. .token.bold {
  93. font-weight: ${theme.fontWeightBold};
  94. }
  95. .token.italic {
  96. font-style: italic;
  97. }
  98. .token.entity {
  99. cursor: help;
  100. }
  101. .line-highlight {
  102. position: absolute;
  103. left: -${space(2)};
  104. right: 0;
  105. background: var(--prism-highlight-background);
  106. box-shadow: inset 5px 0 0 var(--prism-highlight-accent);
  107. z-index: 0;
  108. pointer-events: none;
  109. line-height: inherit;
  110. white-space: pre;
  111. }
  112. }
  113. pre[data-line] {
  114. position: relative;
  115. }
  116. pre[class*='language-'] > code[class*='language-'] {
  117. position: relative;
  118. z-index: 1;
  119. }
  120. `;
  121. const styles = (theme: Theme, isDark: boolean) => css`
  122. body {
  123. .sentry-error-embed-wrapper {
  124. z-index: ${theme.zIndex.sentryErrorEmbed};
  125. }
  126. color: ${theme.textColor};
  127. background: ${theme.backgroundSecondary};
  128. }
  129. abbr {
  130. ${theme.tooltipUnderline()};
  131. }
  132. a {
  133. color: ${theme.linkColor};
  134. &:focus-visible,
  135. &:hover {
  136. color: ${theme.linkHoverColor};
  137. }
  138. }
  139. .group-detail:before {
  140. background: ${theme.border};
  141. }
  142. .form-actions {
  143. border-top-color: ${theme.border};
  144. }
  145. pre,
  146. code {
  147. color: ${theme.textColor};
  148. }
  149. pre {
  150. background-color: ${theme.backgroundSecondary};
  151. white-space: pre-wrap;
  152. overflow-x: auto;
  153. &:focus-visible {
  154. outline: ${theme.focusBorder} auto 1px;
  155. }
  156. }
  157. code {
  158. background-color: transparent;
  159. }
  160. ${prismStyles(theme)}
  161. /**
  162. * See https://web.dev/prefers-reduced-motion/
  163. */
  164. @media (prefers-reduced-motion) {
  165. *,
  166. ::before,
  167. ::after {
  168. animation-delay: -1ms !important;
  169. animation-duration: 0ms !important;
  170. animation-iteration-count: 1 !important;
  171. background-attachment: initial !important;
  172. scroll-behavior: auto !important;
  173. transition-duration: 0s !important;
  174. transition-delay: 0s !important;
  175. }
  176. }
  177. .ReactVirtualized__Grid:focus-visible,
  178. .ReactVirtualized__List:focus-visible {
  179. outline: ${theme.focusBorder} auto 1px;
  180. }
  181. /* Override css in LESS files here as we want to manually control dark mode for now */
  182. ${isDark
  183. ? css`
  184. .box,
  185. .box.box-modal {
  186. background: ${theme.background};
  187. border-color: ${theme.border};
  188. .box-content,
  189. .box-header {
  190. background: ${theme.background};
  191. h1,
  192. h2,
  193. h3,
  194. h4,
  195. h5,
  196. h6 {
  197. color: ${theme.headingColor};
  198. }
  199. a {
  200. color: ${theme.textColor};
  201. }
  202. }
  203. .box-header {
  204. border-bottom-color: ${theme.border};
  205. }
  206. }
  207. .loading .loading-indicator {
  208. border-color: ${theme.backgroundSecondary};
  209. border-left-color: ${theme.purple300};
  210. }
  211. .pattern-bg {
  212. opacity: 1;
  213. filter: invert(1) brightness(0.6);
  214. }
  215. .nav-tabs {
  216. & > li {
  217. &.active {
  218. a {
  219. color: ${theme.textColor} !important;
  220. border-bottom-color: ${theme.active} !important;
  221. }
  222. }
  223. a:hover {
  224. color: ${theme.textColor} !important;
  225. }
  226. }
  227. &.border-bottom {
  228. border-color: ${theme.border};
  229. }
  230. }
  231. ul.crumbs li .table.key-value pre {
  232. color: ${theme.subText};
  233. }
  234. .exception {
  235. border-color: ${theme.innerBorder};
  236. }
  237. .traceback {
  238. border-color: ${theme.border};
  239. &.in-app-traceback {
  240. .frame {
  241. &.leads-to-app {
  242. &.collapsed {
  243. .title {
  244. border-color: ${theme.border};
  245. background: ${theme.background};
  246. }
  247. }
  248. }
  249. }
  250. }
  251. .frame,
  252. .frame.system-frame {
  253. border-top-color: ${theme.border};
  254. &.is-expandable .title:hover {
  255. background-color: ${theme.background};
  256. }
  257. .btn-toggle {
  258. color: ${theme.textColor};
  259. background: transparent;
  260. }
  261. .title {
  262. background-color: ${theme.backgroundSecondary};
  263. }
  264. &.is-expandable .title {
  265. background-color: ${theme.backgroundSecondary};
  266. }
  267. .context {
  268. background: ${theme.background};
  269. table.key-value {
  270. border-color: ${theme.border};
  271. td {
  272. border-color: ${theme.border} !important;
  273. }
  274. }
  275. }
  276. }
  277. }
  278. .group-detail h3 em {
  279. color: ${theme.subText};
  280. }
  281. .event-details-container {
  282. background-color: ${theme.background};
  283. .secondary {
  284. border-left-color: ${theme.border};
  285. }
  286. }
  287. /* Group Details - User context */
  288. .user-widget .avatar {
  289. box-shadow: 0 0 0 5px ${theme.background};
  290. background: ${theme.background};
  291. }
  292. .nav-header a.help-link,
  293. .nav-header span.help-link a {
  294. color: ${theme.subText};
  295. }
  296. /* Global Selection header date picker */
  297. .rdrCalendarWrapper {
  298. background: ${theme.background};
  299. color: ${theme.textColor};
  300. }
  301. .rdrDayDisabled {
  302. background-color: ${theme.backgroundSecondary};
  303. color: ${theme.disabled};
  304. }
  305. .rdrMonthAndYearPickers select {
  306. color: ${theme.textColor};
  307. }
  308. .dropdown-menu {
  309. color: ${theme.textColor};
  310. background-color: ${theme.background} !important;
  311. border: 1px solid ${theme.border};
  312. &:before {
  313. border-bottom-color: ${theme.border};
  314. }
  315. &:after {
  316. border-bottom-color: ${theme.background};
  317. }
  318. &.inverted:before {
  319. border-top-color: ${theme.border};
  320. }
  321. &.inverted:after {
  322. border-top-color: ${theme.background};
  323. }
  324. }
  325. `
  326. : ''}
  327. `;
  328. /**
  329. * Renders an emotion global styles injection component
  330. */
  331. function GlobalStyles({theme, isDark}: {isDark: boolean; theme: Theme}) {
  332. return <Global styles={styles(theme, isDark)} />;
  333. }
  334. export default GlobalStyles;