diff --git a/static/app/components/charts/chartWidgetLoader.stories.tsx b/static/app/components/charts/chartWidgetLoader.stories.tsx index c0369ef9cbbfa5..128fb4ab7091b1 100644 --- a/static/app/components/charts/chartWidgetLoader.stories.tsx +++ b/static/app/components/charts/chartWidgetLoader.stories.tsx @@ -1,7 +1,7 @@ import {Fragment} from 'react'; import types from '!!type-loader!sentry/components/charts/chartWidgetLoader'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; +import {CodeBlock} from 'sentry/components/core/code'; import * as Storybook from 'sentry/stories'; export default Storybook.story('ChartWidgetLoader', (story, APIReference) => { @@ -30,7 +30,7 @@ export default Storybook.story('ChartWidgetLoader', (story, APIReference) => { render these chart widgets).

- {``} + {``} ); }); diff --git a/static/app/components/codeSnippet.stories.tsx b/static/app/components/codeSnippet.stories.tsx deleted file mode 100644 index 8b91497acbc01a..00000000000000 --- a/static/app/components/codeSnippet.stories.tsx +++ /dev/null @@ -1,248 +0,0 @@ -import {Fragment, useState} from 'react'; - -import {addSuccessMessage} from 'sentry/actionCreators/indicator'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; -import {IconStar} from 'sentry/icons'; -import * as Storybook from 'sentry/stories'; - -export default Storybook.story('CodeSnippet', story => { - story('Defaults', () => ( - -

- The component is useful when you want to - render code instructions in onboarding or other setup situations. By default, the - code snippet is able to be copied, selected, and has rounded corners and shows in - light mode. It'll also apply formatting automatically, if the language (passed in - with the - prop) is known. -

- -

JavaScript example:

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} - -

Python example:

- {`sentry_sdk.metrics.incr( - key="button_click", - value=1, - tags={ - "browser": "Firefox", - "app_version": "1.0.0" - } -)`} -
- )); - - story('Props', () => { - const [tab, setTab] = useState('npm'); - - return ( - -

- You can customize the display of the : -

- -

- -

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

with filename

- - {`const myVariable = 'testing';`} - -
-

dark filename

- - {`const myVariable = 'testing';`} - -
-

with tabs

- setTab(t)} - language="javascript" - > - {tab === 'npm' - ? `npm install --save @sentry/browser` - : 'yarn add @sentry/browser'} - -
-

- -

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

- -

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

- -

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

- -

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

- -

- } language="javascript">{`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
- } - filename="yourModule.tsx" - language="javascript" - >{`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

- -

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
- ); - }); - - story('Callbacks', () => { - const [tab, setTab] = useState('npm'); - const onCopy = () => addSuccessMessage('Copied!'); - const onSelectAndCopy = () => - addSuccessMessage( - 'Copied...but you know you can just press the copy button to copy it all, right?' - ); - const onTabClick = () => addSuccessMessage('Clicked a different tab'); - - return ( - -

- You can customize what happens when the user clicks the copy button, after the - user highlights a part of the code snippet, after the user selects and manually - copies the code snippet, or when a tab is clicked by specifying the callback. -

-

- -

-

Try pressing the copy button:

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

- -

-

Try manually selecting and copying code:

- {`Sentry.init({ - // Note, Replay is NOT instantiated below: - integrations: [], -}); - -// Sometime later -const { replayIntegration } = await import("@sentry/browser"); -Sentry.addIntegration(replayIntegration());`} -
-

- -

-

Try switching tabs:

- { - setTab(t); - onTabClick(); - }} - language="javascript" - > - {tab === 'npm' - ? `npm install --save @sentry/browser` - : 'yarn add @sentry/browser'} - {' '} -
- ); - }); -}); diff --git a/static/app/components/confirmDelete.tsx b/static/app/components/confirmDelete.tsx index f46b6c9a5cb19d..3b2c2f6f9c938c 100644 --- a/static/app/components/confirmDelete.tsx +++ b/static/app/components/confirmDelete.tsx @@ -2,7 +2,7 @@ import {Fragment, useId} from 'react'; import Confirm from 'sentry/components/confirm'; import {Alert} from 'sentry/components/core/alert'; -import {InlineCode} from 'sentry/components/core/inlineCode'; +import {InlineCode} from 'sentry/components/core/code'; import {Input} from 'sentry/components/core/input'; import FieldGroup from 'sentry/components/forms/fieldGroup'; import {t} from 'sentry/locale'; diff --git a/static/app/components/core/code/codeBlock.mdx b/static/app/components/core/code/codeBlock.mdx new file mode 100644 index 00000000000000..7a9355b4da952e --- /dev/null +++ b/static/app/components/core/code/codeBlock.mdx @@ -0,0 +1,355 @@ +--- +title: CodeBlock +description: CodeBlock displays multi-line code snippets with syntax highlighting, copy functionality, and support for tabs, filenames, and line highlighting. +source: 'sentry/components/core/code' +resources: + js: https://github.com/getsentry/sentry/blob/master/static/app/components/core/code/codeBlock.tsx + a11y: + WCAG 1.4.3: https://www.w3.org/TR/WCAG22/#contrast-minimum + WCAG 1.4.8: https://www.w3.org/TR/WCAG22/#visual-presentation +--- + +import {Fragment, useState} from 'react'; + +import {addSuccessMessage} from 'sentry/actionCreators/indicator'; +import {CodeBlock} from 'sentry/components/core/code'; +import {IconStar} from 'sentry/icons'; +import * as Storybook from 'sentry/stories'; + +import types from '!!type-loader!sentry/components/core/code/codeBlock'; + +export {types}; + +export const sampleJavaScript = `Sentry.init({ + // Note, Replay is NOT instantiated below: + integrations: [], +}); + +// Sometime later +const { replayIntegration } = await import("@sentry/browser"); +Sentry.addIntegration(replayIntegration());`; + +export const samplePython = `sentry_sdk.metrics.incr( + key="button_click", + value=1, + tags={ + "browser": "Firefox", + "app_version": "1.0.0" + } +)`; + +The `` component is useful when you want to render code instructions in onboarding or other setup situations. By default, code blocks can be copied, selected, have rounded corners, and display in light mode. They also apply syntax highlighting automatically if the language is specified. + +```jsx +{sampleJavaScript} +``` + +## Basic Usage + +Use `` to display multi-line code snippets with syntax highlighting. + + +

JavaScript example:

+ {sampleJavaScript} + +

Python example:

+ {samplePython} +
+```jsx +{sampleJavaScript} + +{samplePython} +``` + +## Dark Mode + +Use the `dark` prop to display the code block with a dark theme. + + + + {sampleJavaScript} + + +```jsx + + {sampleJavaScript} + +``` + +## With Filename + +Display a filename at the top of the code block using the `filename` prop. + + + + {`const myVariable = 'testing';`} + + +```jsx + + {`const myVariable = 'testing';`} + +``` + +### Dark Filename + + + + {`const myVariable = 'testing';`} + + +```jsx + + {`const myVariable = 'testing';`} + +``` + +## With Tabs + +Use the `tabs`, `selectedTab`, and `onTabClick` props to create tabbed code blocks for showing different installation methods or configurations. + +export function TabExample() { + const [tab, setTab] = useState('npm'); + return ( + setTab(t)} + language="bash" + > + {tab === 'npm' ? `npm install --save @sentry/browser` : 'yarn add @sentry/browser'} + + ); +} + + + + +```jsx const [tab, setTab] = useState('npm'); + + setTab(t)} + language="bash" +> + {tab === 'npm' ? `npm install --save @sentry/browser` : 'yarn add @sentry/browser'} + +``` + +## Without Rounded Corners + +Set `isRounded={false}` to remove rounded corners. + + + + {sampleJavaScript} + + +```jsx + + {sampleJavaScript} + +``` + +## Hide Copy Button + +Use `hideCopyButton` to hide the copy button in the top right. + + + + {sampleJavaScript} + + +```jsx + + {sampleJavaScript} + +``` + +## Disable User Selection + +Use `disableUserSelection` to prevent users from manually selecting and copying text. Useful when loading parts of a code snippet. + + + + {sampleJavaScript} + + +```jsx + + {sampleJavaScript} + +``` + +## With Icon + +Add a custom icon next to the copy button using the `icon` prop. + + + } language="javascript"> + {sampleJavaScript} + +
+ } filename="yourModule.tsx" language="javascript"> + {sampleJavaScript} + +
+```jsx +} language="javascript"> + {sampleJavaScript} + + +} filename="yourModule.tsx" language="javascript"> + {sampleJavaScript} + +``` + +## Line Highlighting + +Use `linesToHighlight` to visually highlight specific line numbers. + + + + {sampleJavaScript} + + +```jsx + + {sampleJavaScript} + +``` + +## Callbacks + +Customize behavior with callback props. + +### onCopy Callback + +Fires when the user clicks the copy button. + +export function OnCopyExample() { + const onCopy = () => { + addSuccessMessage('Copied!'); + }; + return ( + + {sampleJavaScript} + + ); +} + + +

Try pressing the copy button:

+ +
+ +```jsx +// track analytics, show toast, etc +const onCopy = () => addSuccessMessage('Copied!'); + + + {sampleJavaScript} +; +``` + +### onSelectAndCopy Callback + +Fires when the user manually selects and copies code. + +export function OnSelectAndCopyExample() { + const onSelectAndCopy = () => { + addSuccessMessage( + 'Copied...but you know you can just press the copy button to copy it all, right?' + ); + }; + return ( + + {sampleJavaScript} + + ); +} + + +

Try manually selecting and copying code:

+ +
+ +```jsx +const onSelectAndCopy = () => addSuccessMessage('Copied...but you know you can just +press the copy button?'); + + + {sampleJavaScript} + +``` + +### onTabClick Callback + +Fires when the user switches tabs. + +export function OnTabClickExample() { + const [tab, setTab] = useState('npm'); + function handleTabClick(t) { + setTab(t); + addSuccessMessage('Clicked a different tab'); + }; + +return ( + + +{tab === 'npm' ? `npm install --save @sentry/browser` : 'yarn add @sentry/browser'} + + +); +} + + +

Try switching tabs:

+ +
+ +```jsx +const [tab, setTab] = useState('npm'); +const onTabClick = () => addSuccessMessage('Clicked a different tab'); + + { + setTab(t); + onTabClick(); + }} + language="bash" +> + {tab === 'npm' ? `npm install --save @sentry/browser` : 'yarn add @sentry/browser'} +; +``` + +## Related Components + +For different code display needs, consider these alternatives: + +- [**``**](/stories/core/inline-code): Use for short code snippets within text content +- [**``**](/stories/typography/prose): Use for long-form content that may contain code elements +- [**``**](/stories/typography/text#monospace): Use for monospace text that isn't necessarily code + +## Accessibility + +`` uses semantic HTML with proper `
` and `` elements for screen readers. The copy button includes proper ARIA labels and keyboard navigation support. The component maintains sufficient color contrast in both light and dark modes to meet WCAG 2.2 AA requirements.
diff --git a/static/app/components/codeSnippet.tsx b/static/app/components/core/code/codeBlock.tsx
similarity index 98%
rename from static/app/components/codeSnippet.tsx
rename to static/app/components/core/code/codeBlock.tsx
index fd854a09e77038..5d438e7f4da68c 100644
--- a/static/app/components/codeSnippet.tsx
+++ b/static/app/components/core/code/codeBlock.tsx
@@ -11,7 +11,7 @@ import {loadPrismLanguage} from 'sentry/utils/prism';
 // eslint-disable-next-line no-restricted-imports -- @TODO(jonasbadalic): Remove theme import
 import {darkTheme} from 'sentry/utils/theme';
 
-interface CodeSnippetProps {
+interface CodeBlockProps {
   children: string;
   className?: string;
   dark?: boolean;
@@ -67,7 +67,7 @@ interface CodeSnippetProps {
   }>;
 }
 
-export function CodeSnippet({
+export function CodeBlock({
   children,
   className,
   dark,
@@ -85,7 +85,7 @@ export function CodeSnippet({
   onTabClick,
   selectedTab,
   tabs,
-}: CodeSnippetProps) {
+}: CodeBlockProps) {
   const ref = useRef(null);
   const theme = useTheme();
 
diff --git a/static/app/components/core/code/index.tsx b/static/app/components/core/code/index.tsx
new file mode 100644
index 00000000000000..62b28822695afc
--- /dev/null
+++ b/static/app/components/core/code/index.tsx
@@ -0,0 +1,2 @@
+export {InlineCode} from './inlineCode';
+export {CodeBlock} from './codeBlock';
diff --git a/static/app/components/core/inlineCode/index.mdx b/static/app/components/core/code/inlineCode.mdx
similarity index 91%
rename from static/app/components/core/inlineCode/index.mdx
rename to static/app/components/core/code/inlineCode.mdx
index a8bd9922df3f2d..4f7c9bfcd08dac 100644
--- a/static/app/components/core/inlineCode/index.mdx
+++ b/static/app/components/core/code/inlineCode.mdx
@@ -1,7 +1,7 @@
 ---
 title: InlineCode
 description: InlineCode provides styling for short snippets of code within text content, such as variable names, function names, or short commands.
-source: 'sentry/components/core/inlineCode'
+source: 'sentry/components/core/code'
 status: stable
 resources:
   js: https://github.com/getsentry/sentry/blob/master/static/app/components/core/inlineCode/index.tsx
@@ -10,12 +10,12 @@ resources:
     WCAG 1.4.4: https://www.w3.org/TR/WCAG22/#resize-text
 ---
 
-import {InlineCode} from 'sentry/components/core/inlineCode';
+import {InlineCode} from 'sentry/components/core/code/inlineCode';
 import {Text} from 'sentry/components/core/text';
 import {Prose} from 'sentry/components/core/text/prose';
 import * as Storybook from 'sentry/stories';
 
-import types from '!!type-loader!sentry/components/core/inlineCode';
+import types from '!!type-loader!sentry/components/core/code/inlineCode';
 
 export {types};
 
@@ -138,14 +138,6 @@ For long form content, `` elements are automatically styled within the [`<
 
 ```
 
-## Related Components
-
-For different code display needs, consider these alternatives:
-
-- **``**: Use for long-form content that may contain multiple `` elements with proper spacing and typography
-- **``**: Use for multi-line code blocks with syntax highlighting and copy functionality
-- **``**: Use for monospace text that isn't necessarily code (like IDs or timestamps)
-
 
   
     

@@ -175,6 +167,14 @@ For different code display needs, consider these alternatives: ``` +## Related Components + +For different code display needs, consider these alternatives: + +- [**``**](/stories/core/code-block): Use for multi-line code snippets with syntax highlighting +- [**``**](/stories/typography/prose): Use for long-form content that may contain code elements +- [**``**](/stories/typography/text#monospace): Use for monospace text that isn't necessarily code + ## Accessibility `` renders as a semantic `` element, which provides appropriate meaning to screen readers and other assistive technologies. The component maintains sufficient color contrast to meet WCAG 2.2 AA requirements. diff --git a/static/app/components/core/inlineCode/index.tsx b/static/app/components/core/code/inlineCode.tsx similarity index 100% rename from static/app/components/core/inlineCode/index.tsx rename to static/app/components/core/code/inlineCode.tsx diff --git a/static/app/components/core/text/prose.tsx b/static/app/components/core/text/prose.tsx index 8c431cac26e158..2603b4d9f07b12 100644 --- a/static/app/components/core/text/prose.tsx +++ b/static/app/components/core/text/prose.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; -import {inlineCodeStyles} from 'sentry/components/core/inlineCode'; +import {inlineCodeStyles} from 'sentry/components/core/code/inlineCode'; type ProsePropsWithChildren = { as?: T; diff --git a/static/app/components/events/interfaces/performance/spanEvidenceKeyValueList.tsx b/static/app/components/events/interfaces/performance/spanEvidenceKeyValueList.tsx index 855dacce38df94..19c1642e37ca40 100644 --- a/static/app/components/events/interfaces/performance/spanEvidenceKeyValueList.tsx +++ b/static/app/components/events/interfaces/performance/spanEvidenceKeyValueList.tsx @@ -7,8 +7,8 @@ import kebabCase from 'lodash/kebabCase'; import mapValues from 'lodash/mapValues'; import ClippedBox from 'sentry/components/clippedBox'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {LinkButton} from 'sentry/components/core/button/linkButton'; +import {CodeBlock} from 'sentry/components/core/code'; import {Link} from 'sentry/components/core/link'; import {Tooltip} from 'sentry/components/core/tooltip'; import {getKeyValueListData as getRegressionIssueKeyValueList} from 'sentry/components/events/eventStatisticalDetector/eventRegressionSummary'; @@ -620,7 +620,7 @@ function getSpanEvidenceValue(span: Span | null) { return `${span.op} - ${span.description}`; } -const StyledCodeSnippet = styled(CodeSnippet)` +const StyledCodeSnippet = styled(CodeBlock)` pre { /* overflow is set to visible in global styles so need to enforce auto here */ overflow: auto !important; diff --git a/static/app/components/events/interfaces/request/index.tsx b/static/app/components/events/interfaces/request/index.tsx index c28bee499f09d8..5066c0a93a145f 100644 --- a/static/app/components/events/interfaces/request/index.tsx +++ b/static/app/components/events/interfaces/request/index.tsx @@ -2,7 +2,7 @@ import {Fragment, useState} from 'react'; import styled from '@emotion/styled'; import ClippedBox from 'sentry/components/clippedBox'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; +import {CodeBlock} from 'sentry/components/core/code'; import {Flex} from 'sentry/components/core/layout'; import {ExternalLink} from 'sentry/components/core/link'; import {SegmentedControl} from 'sentry/components/core/segmentedControl'; @@ -141,7 +141,7 @@ export function Request({data, event}: RequestProps) { > {title} {view === 'curl' ? ( - {getCurlCommand(data)} + {getCurlCommand(data)} ) : ( @@ -180,7 +180,7 @@ export function Request({data, event}: RequestProps) { className="request" > {view === 'curl' ? ( - {getCurlCommand(data)} + {getCurlCommand(data)} ) : ( {defined(data.query) && ( diff --git a/static/app/components/events/interfaces/sourceMapsDebuggerModal.tsx b/static/app/components/events/interfaces/sourceMapsDebuggerModal.tsx index f7cb7a74702db5..a1371634964ede 100644 --- a/static/app/components/events/interfaces/sourceMapsDebuggerModal.tsx +++ b/static/app/components/events/interfaces/sourceMapsDebuggerModal.tsx @@ -8,10 +8,10 @@ import GoodStackTraceExample from 'sentry-images/issue_details/good-stack-trace- import type {ModalRenderProps} from 'sentry/actionCreators/modal'; import {openModal} from 'sentry/actionCreators/modal'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {ContentSliderDiff} from 'sentry/components/contentSliderDiff'; import {Alert} from 'sentry/components/core/alert'; import {LinkButton} from 'sentry/components/core/button/linkButton'; +import {CodeBlock} from 'sentry/components/core/code'; import {Flex} from 'sentry/components/core/layout'; import {ExternalLink, Link} from 'sentry/components/core/link'; import {TabList, TabPanels, Tabs} from 'sentry/components/core/tabs'; @@ -2077,7 +2077,7 @@ const WizardInstructionParagraph = styled('p')` margin-bottom: ${space(1)}; `; -const InstructionCodeSnippet = styled(CodeSnippet)` +const InstructionCodeSnippet = styled(CodeBlock)` margin: ${space(1)} 0 ${space(2)}; `; diff --git a/static/app/components/globalDrawer/index.stories.tsx b/static/app/components/globalDrawer/index.stories.tsx index 08b018ad3871eb..30abf94c046931 100644 --- a/static/app/components/globalDrawer/index.stories.tsx +++ b/static/app/components/globalDrawer/index.stories.tsx @@ -1,9 +1,9 @@ import {Fragment} from 'react'; import styled from '@emotion/styled'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {Alert} from 'sentry/components/core/alert'; import {Button} from 'sentry/components/core/button'; +import {CodeBlock} from 'sentry/components/core/code'; import useDrawer from 'sentry/components/globalDrawer'; import {DrawerBody, DrawerHeader} from 'sentry/components/globalDrawer/components'; import * as Storybook from 'sentry/stories'; @@ -37,7 +37,7 @@ export default Storybook.story('GlobalDrawer', story => { return ( - + {`import useDrawer from 'sentry/components/globalDrawer'; import {DrawerBody, DrawerHeader} from 'sentry/components/globalDrawer/components'; @@ -66,7 +66,7 @@ function MyDrawer({title}: {title: string}) { ); } `} - +

Open Drawer
@@ -97,7 +97,7 @@ function MyDrawer({title}: {title: string}) { closeDrawer. The close button can be inside or outside the drawer.

- + {`function MyPage() { const {openDrawer, closeDrawer} = useDrawer(); @@ -111,7 +111,7 @@ function MyDrawer({title}: {title: string}) { return `} - + @@ -207,7 +207,7 @@ function MyDrawer({title}: {title: string}) { URL.

- + {`import {useEffect} from 'react'; import useDrawer from 'sentry/components/globalDrawer'; import {useLocation} from 'sentry/utils/useLocation'; @@ -236,7 +236,7 @@ function ModalContent() { return

Ahoy there

; } `} -
+

You don't need to worry about closing the drawer, since it'll close automatically @@ -260,7 +260,7 @@ function ModalContent() { padding, scrolling, and overflow.

- + {`import {DrawerBody, DrawerHeader} from 'sentry/components/globalDrawer/components'; `} - + openDrawer( diff --git a/static/app/components/keyValueData/index.stories.tsx b/static/app/components/keyValueData/index.stories.tsx index 239475dd71d65a..a9ac9b2047d6e3 100644 --- a/static/app/components/keyValueData/index.stories.tsx +++ b/static/app/components/keyValueData/index.stories.tsx @@ -1,9 +1,9 @@ import {Fragment} from 'react'; import {useTheme, type Theme} from '@emotion/react'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {Alert} from 'sentry/components/core/alert'; import {Button} from 'sentry/components/core/button'; +import {CodeBlock} from 'sentry/components/core/code'; import { KeyValueData, type KeyValueDataContentProps, @@ -13,9 +13,9 @@ import * as Storybook from 'sentry/stories'; export default Storybook.story('KeyValueData', story => { story('Usage', () => ( - + import KeyValueData from 'sentry/components/keyValueData'; - + )); story('', () => { const theme = useTheme(); @@ -137,13 +137,13 @@ export default Storybook.story('KeyValueData', story => { children.

- + {` `} - +

It should be noted that the number of items per card, or content size is not diff --git a/static/app/components/modals/importDashboardFromFileModal.tsx b/static/app/components/modals/importDashboardFromFileModal.tsx index 9990e785677fab..c54c255e6bd0fd 100644 --- a/static/app/components/modals/importDashboardFromFileModal.tsx +++ b/static/app/components/modals/importDashboardFromFileModal.tsx @@ -6,8 +6,8 @@ import {createDashboard} from 'sentry/actionCreators/dashboards'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import type {ModalRenderProps} from 'sentry/actionCreators/modal'; import type {Client} from 'sentry/api'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {Button} from 'sentry/components/core/button'; +import {CodeBlock} from 'sentry/components/core/code'; import {IconUpload} from 'sentry/icons'; import {t} from 'sentry/locale'; import type {Organization} from 'sentry/types/organization'; @@ -121,7 +121,7 @@ function ImportDashboardFromFileModal({

{t('Preview')}

- {dashboardData} + {dashboardData} )} diff --git a/static/app/components/onboarding/gettingStartedDoc/deprecatedPlatformInfo.tsx b/static/app/components/onboarding/gettingStartedDoc/deprecatedPlatformInfo.tsx index 9779208ff7ae44..241db4a9c212bf 100644 --- a/static/app/components/onboarding/gettingStartedDoc/deprecatedPlatformInfo.tsx +++ b/static/app/components/onboarding/gettingStartedDoc/deprecatedPlatformInfo.tsx @@ -1,7 +1,7 @@ import styled from '@emotion/styled'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {Alert} from 'sentry/components/core/alert'; +import {CodeBlock} from 'sentry/components/core/code'; import {Stack} from 'sentry/components/core/layout'; import {ExternalLink} from 'sentry/components/core/link'; import {Text} from 'sentry/components/core/text'; @@ -26,9 +26,9 @@ export function DeprecatedPlatformInfo({platform, dsn}: DeprecatedPlatformInfoPr )}
- + {dsn.public} - + {tct( diff --git a/static/app/components/onboarding/gettingStartedDoc/onboardingCodeSnippet.tsx b/static/app/components/onboarding/gettingStartedDoc/onboardingCodeSnippet.tsx index fe02f1d41d7775..bb389a8f2974e2 100644 --- a/static/app/components/onboarding/gettingStartedDoc/onboardingCodeSnippet.tsx +++ b/static/app/components/onboarding/gettingStartedDoc/onboardingCodeSnippet.tsx @@ -2,12 +2,12 @@ import {Fragment, useCallback, useMemo, useState} from 'react'; import {createPortal} from 'react-dom'; import beautify from 'js-beautify'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; +import {CodeBlock} from 'sentry/components/core/code'; import {AuthTokenGenerator} from 'sentry/components/onboarding/gettingStartedDoc/authTokenGenerator'; import {PACKAGE_LOADING_PLACEHOLDER} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; interface OnboardingCodeSnippetProps - extends Omit, 'onAfterHighlight'> {} + extends Omit, 'onAfterHighlight'> {} /** * Replaces tokens in a DOM element with a span element. @@ -47,7 +47,7 @@ export function OnboardingCodeSnippet({ return ( - + {authTokenNodes.map(node => createPortal(, node))} ); diff --git a/static/app/components/replays/breadcrumbs/breadcrumbCodeSnippet.tsx b/static/app/components/replays/breadcrumbs/breadcrumbCodeSnippet.tsx index b6a81736084306..a38e39bb1e2107 100644 --- a/static/app/components/replays/breadcrumbs/breadcrumbCodeSnippet.tsx +++ b/static/app/components/replays/breadcrumbs/breadcrumbCodeSnippet.tsx @@ -1,7 +1,7 @@ import styled from '@emotion/styled'; import beautify from 'js-beautify'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; +import {CodeBlock} from 'sentry/components/core/code'; import Placeholder from 'sentry/components/placeholder'; import type {Extraction} from 'sentry/utils/replays/extractDomNodes'; import type {ReplayFrame} from 'sentry/utils/replays/types'; @@ -34,9 +34,9 @@ export function BreadcrumbCodeSnippet({ return extraction?.html?.map(html => ( - + {beautify.html(html, {indent_size: 2})} - + )); } diff --git a/static/app/components/searchQueryBuilder/index.stories.tsx b/static/app/components/searchQueryBuilder/index.stories.tsx index eb4b4d97f62040..76fbe1af557210 100644 --- a/static/app/components/searchQueryBuilder/index.stories.tsx +++ b/static/app/components/searchQueryBuilder/index.stories.tsx @@ -1,7 +1,7 @@ import {Fragment, useState} from 'react'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {Button} from 'sentry/components/core/button'; +import {CodeBlock} from 'sentry/components/core/code'; import MultipleCheckbox from 'sentry/components/forms/controls/multipleCheckbox'; import {ItemType} from 'sentry/components/searchBar/types'; import {SearchQueryBuilder} from 'sentry/components/searchQueryBuilder'; @@ -851,7 +851,7 @@ export default Storybook.story('SearchQueryBuilder', story => { implementation, clicking the button will open the dropdown for the first filter with the focusOverride prop.

- + {` function OpenDropdownButton() { const {dispatch} = useSearchQueryBuilder(); @@ -884,7 +884,7 @@ function SearchQueryBuilderExample(queryBuilderProps: SearchQueryBuilderProps) { ) } `} - +

The following is the above code in action:

diff --git a/static/app/components/structuredEventData/index.stories.tsx b/static/app/components/structuredEventData/index.stories.tsx index c2295a443dd770..d29f7c066505f0 100644 --- a/static/app/components/structuredEventData/index.stories.tsx +++ b/static/app/components/structuredEventData/index.stories.tsx @@ -1,7 +1,7 @@ import {Fragment, useState} from 'react'; import {addSuccessMessage} from 'sentry/actionCreators/indicator'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; +import {CodeBlock} from 'sentry/components/core/code'; import StructuredEventData from 'sentry/components/structuredEventData'; import * as Storybook from 'sentry/stories'; @@ -143,14 +143,14 @@ export default Storybook.story('StructuredEventData', story => { customize when and how certain data types are displayed.

Input:

- {`data: {nil: null, bool: 'this_should_look_like_a_boolean'}`} + {`data: {nil: null, bool: 'this_should_look_like_a_boolean'}`}

Config:

- + {`const config = { renderNull: () => 'nulllllll', isBoolean: value => value === 'this_should_look_like_a_boolean', }`} - +

Output:

{ any other custom formatting), you can set the isString with something like this:

- + {`const config = { isString: (v: any) => { return typeof v === 'string'; }, }; `} - + ); }); diff --git a/static/app/components/timeline/index.stories.tsx b/static/app/components/timeline/index.stories.tsx index 02685af464b12a..073d8a91ee2820 100644 --- a/static/app/components/timeline/index.stories.tsx +++ b/static/app/components/timeline/index.stories.tsx @@ -1,7 +1,7 @@ import {Fragment} from 'react'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {Button} from 'sentry/components/core/button'; +import {CodeBlock} from 'sentry/components/core/code'; import {DateTime} from 'sentry/components/dateTime'; import {StructuredData} from 'sentry/components/structuredEventData'; import {Timeline} from 'sentry/components/timeline'; @@ -17,9 +17,9 @@ import * as Storybook from 'sentry/stories'; export default Storybook.story('Timeline', story => { story('Usage', () => ( - + import Timeline from 'sentry/components/timeline'; - + )); story('', () => ( @@ -29,11 +29,11 @@ export default Storybook.story('Timeline', story => { {''}. It generally contains descriptive text.

- + {` {someText} `} - +

Example
{ payloads.

- + {` `} - +

Example
{
  • Create a usage hook to refine types.
  • Add a tour key to save the viewed/dismissed status.
  • - + {`import {createContext, useContext} from 'react'; import {TourElement, type TourElementProps} from 'sentry/components/tours/components'; @@ -123,7 +123,7 @@ function useMyTour(): TourContextType { export const MY_TOUR_KEY = 'tour.my_tour'; `} - + )); @@ -134,7 +134,7 @@ export const MY_TOUR_KEY = 'tour.my_tour'; and pass in the context, and ordered steps you created earlier.

    - + {` orderedStepIds={ORDERED_MY_TOUR} tourContext={MyTourContext} @@ -142,13 +142,13 @@ export const MY_TOUR_KEY = 'tour.my_tour'; > {/* All focused elements in the tour should be within this provider */} `} - +

    Now, you can use the component to wrap the component you wish to highlight.

    - + {`// Before... @@ -162,7 +162,7 @@ export const MY_TOUR_KEY = 'tour.my_tour'; `} - +

    Then, whenever you'd like to start your tour, just import your context and call @@ -176,7 +176,7 @@ export const MY_TOUR_KEY = 'tour.my_tour'; isRegistered property of the context.
    - + {`function StartMyTourButton() { const {startTour, isRegistered} = useMyTour(); return ( @@ -188,7 +188,7 @@ export const MY_TOUR_KEY = 'tour.my_tour'; ); }`} - +
    diff --git a/static/app/data/forms/projectGeneralSettings.tsx b/static/app/data/forms/projectGeneralSettings.tsx index 8da80284327e1a..107d0edc9fedef 100644 --- a/static/app/data/forms/projectGeneralSettings.tsx +++ b/static/app/data/forms/projectGeneralSettings.tsx @@ -2,8 +2,8 @@ import styled from '@emotion/styled'; import {PlatformIcon} from 'platformicons'; import {hasEveryAccess} from 'sentry/components/acl/access'; -import {CodeSnippet} from 'sentry/components/codeSnippet'; import {Button} from 'sentry/components/core/button'; +import {CodeBlock} from 'sentry/components/core/code'; import {Flex} from 'sentry/components/core/layout'; import {Link} from 'sentry/components/core/link'; import {createFilter} from 'sentry/components/forms/controls/reactSelectWrapper'; @@ -145,9 +145,9 @@ export const fields = { examples: ( + {`https://example.com\n*.example.com\n*:80\n*`} - + } >