Skip to content

Commit

Permalink
Remove pre & code from globalstyles (streamlit#9693)
Browse files Browse the repository at this point in the history
## Describe your changes

Right now, the styles for `pre` and `code` tags come from two different
places: the `globalStyles.ts` file, as well as our `styled-components`
in our StreamlitMarkdown code. This PR merges the globalStyles CSS into
the styled-components.

## GitHub Issue Link (if applicable)

## Testing Plan

- Since this should only move the location from which the styles are
defined and applied, the e2e tests should capture and style deviation.
- Added missing e2e_playwright snapshot tests for the
websocket-disconnect error dialog and the compiler-error dialog
---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.

---------

Co-authored-by: Lukas Masuch <[email protected]>
  • Loading branch information
raethlein and lukasmasuch authored Oct 23, 2024
1 parent 502213c commit 8d7c55e
Show file tree
Hide file tree
Showing 43 changed files with 176 additions and 99 deletions.
4 changes: 2 additions & 2 deletions .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

# In addition to the standard set of exclusions, omit all tests:
extend-exclude = ["lib/streamlit/proto", "lib/streamlit/emojis.py"]
extend-exclude = ["lib/streamlit/proto", "lib/streamlit/emojis.py", "e2e_playwright/compilation_error_dialog.py"]
include = [
"lib/**/*.py",
"lib/**/*.pyi",
Expand Down Expand Up @@ -64,7 +64,7 @@ ignore = [
exclude = [
"lib/streamlit/vendor/**",
"scripts/**",
".github/**",
".github/**"
]

[lint.per-file-ignores]
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions e2e_playwright/compilation_error_dialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2024)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import streamlit as st

# some invalid syntax so that we trigger the compilation error dialog
# if st.button("Trigger compilation error"):
123 foo # noqa: E999
30 changes: 30 additions & 0 deletions e2e_playwright/compilation_error_dialog_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2024)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from playwright.sync_api import Page, expect

from e2e_playwright.conftest import ImageCompareFunction


def test_compilation_error_dialog(
page: Page, app_port: int, assert_snapshot: ImageCompareFunction
):
# Do the navigation manually because our app fixture waits for the app to run, but
# with the compilation error the app never runs
page.goto(f"http://localhost:{app_port}/")
dialog = page.get_by_role("dialog")
expect(dialog).to_be_visible(timeout=10000)
# make sure that the close-x button is not focused
dialog.blur(timeout=0)
assert_snapshot(dialog, name="compilation_error-dialog")
2 changes: 2 additions & 0 deletions e2e_playwright/st_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ def hello():
with st.expander("`st.markdown` code usage", expanded=True):
st.markdown("```python\n" + code + "\n```")
st.markdown("```python\n" + code + "\n```")
st.markdown("[a link with `code`](https://streamlit.io)")


long_string = "Testing line wrapping: " + "foo bar baz " * 10 + "{EOL}"

Expand Down
15 changes: 14 additions & 1 deletion e2e_playwright/websocket_disconnect_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@

from playwright.sync_api import Page, expect

from e2e_playwright.conftest import ImageCompareFunction

def test_disconnecting_disables_widgets_correctly(app: Page):

def test_disconnected_states(app: Page, assert_snapshot: ImageCompareFunction):
expect(app.get_by_test_id("stButton").locator("button")).not_to_have_attribute(
"disabled", ""
)
Expand Down Expand Up @@ -57,3 +59,14 @@ def test_disconnecting_disables_widgets_correctly(app: Page):
app.mouse.down()

expect(app.get_by_test_id("stMarkdown").first).to_contain_text("Value 1: 25")

# After some time the disconnected dialog will appear.
# It would be nicer to have this in a separate function, but we can't do that easily
# because the runtime is shutdown for all test functions. We would need to start the
# runtime again somehow or move this to a separate file.
dialog = app.get_by_role("dialog")
# the dialog might need a moment to appear after shutting down the runtime
expect(dialog).to_be_visible(timeout=20000)
# make sure that the close-x button is not focused
dialog.blur(timeout=0)
assert_snapshot(dialog, name="websocket_connection-disconnected_dialog")
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

import React from "react"

import { StyledInlineCode } from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"

import { IDeployErrorDialog } from "./types"
import { StyledParagraph } from "./styled-components"

Expand All @@ -24,8 +26,8 @@ function ModuleIsNotAdded(module: string): IDeployErrorDialog {
title: "Unable to deploy",
body: (
<StyledParagraph>
The app’s main file <code>{module}</code> has not been pushed to
GitHub. Please add it to continue.
The app’s main file <StyledInlineCode>{module}</StyledInlineCode> has
not been pushed to GitHub. Please add it to continue.
</StyledParagraph>
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ exports[`DeployErrorDialog - ModuleIsNotAdded should render without crashing 1`]
Object {
"body": <StyledParagraph>
The app’s main file
<code>
<StyledInlineCode>
module
</code>
</StyledInlineCode>
has not been pushed to GitHub. Please add it to continue.
</StyledParagraph>,
"title": "Unable to deploy",
Expand Down
16 changes: 11 additions & 5 deletions frontend/app/src/components/StreamlitDialog/StreamlitDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ import {
StreamlitMarkdown,
} from "@streamlit/lib"
import { STREAMLIT_HOME_URL } from "@streamlit/app/src/urls"
import {
StyledCode,
StyledInlineCode,
StyledPre,
} from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"

import { SettingsDialog, Props as SettingsDialogProps } from "./SettingsDialog"
import ThemeCreatorDialog, {
Expand Down Expand Up @@ -195,7 +200,8 @@ function clearCacheDialog(props: ClearCacheProps): ReactElement {
</div>
<div>
This will remove all cached entries from functions using{" "}
<code>@st.cache_data</code> and <code>@st.cache_resource</code>.
<StyledInlineCode>@st.cache_data</StyledInlineCode> and{" "}
<StyledInlineCode>@st.cache_resource</StyledInlineCode>.
</div>
</ModalBody>
<ModalFooter>
Expand Down Expand Up @@ -229,11 +235,11 @@ function scriptCompileErrorDialog(
<ModalHeader>Script execution error</ModalHeader>
<ModalBody>
<div>
<pre>
<code>
<StyledPre>
<StyledCode>
{props.exception ? props.exception.message : "No message"}
</code>
</pre>
</StyledCode>
</StyledPre>
</div>
</ModalBody>
<ModalFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
toThemeInput,
UISelectbox,
} from "@streamlit/lib"
import { StyledInlineCode } from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"

import {
StyledBackButton,
Expand Down Expand Up @@ -302,8 +303,8 @@ const ThemeCreatorDialog = (props: Props): ReactElement => {
<StyledSmall>
To save your changes, copy your custom theme into the clipboard
and paste it into the
<code>[theme]</code> section of your{" "}
<code>.streamlit/config.toml</code> file.
<StyledInlineCode>[theme]</StyledInlineCode> section of your{" "}
<StyledInlineCode>.streamlit/config.toml</StyledInlineCode> file.
</StyledSmall>
</StyledFullRow>

Expand Down
5 changes: 3 additions & 2 deletions frontend/app/src/connection/WebsocketConnection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
StyledBashCode,
WebsocketConnection,
} from "@streamlit/app/src/connection/WebsocketConnection"
import { StyledPre } from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"

const MOCK_ALLOWED_ORIGINS_CONFIG = {
allowedOrigins: ["list", "of", "allowed", "origins"],
Expand Down Expand Up @@ -280,9 +281,9 @@ describe("doInitPings", () => {
Is Streamlit still running? If you accidentally stopped Streamlit,
just restart it in your terminal:
</p>
<pre>
<StyledPre>
<StyledBashCode>streamlit run yourscript.py</StyledBashCode>
</pre>
</StyledPre>
</Fragment>
)

Expand Down
5 changes: 3 additions & 2 deletions frontend/app/src/connection/WebsocketConnection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import React, { Fragment } from "react"
import styled from "@emotion/styled"
import axios from "axios"

import { StyledPre } from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"
import {
isNullOrUndefined,
notNullOrUndefined,
Expand Down Expand Up @@ -658,9 +659,9 @@ export function doInitPings(
Is Streamlit still running? If you accidentally stopped Streamlit,
just restart it in your terminal:
</p>
<pre>
<StyledPre>
<StyledBashCode>streamlit run yourscript.py</StyledBashCode>
</pre>
</StyledPre>
</Fragment>
)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,45 @@
*/

import styled from "@emotion/styled"
import { Theme } from "@emotion/react"

const codeLink = {
// Streamline the style when inside anchors to avoid broken underline and more
"a > &": {
color: "inherit",
},
}

export const StyledInlineCode = styled.code(({ theme }) => ({
padding: "0.2em 0.4em",
wordWrap: "break-word",
margin: 0,
borderRadius: theme.radii.md,
background: theme.colors.codeHighlightColor,
color: theme.colors.codeTextColor,

...codeLink,
}))

const codeBlockStyle = (theme: Theme): React.CSSProperties => ({
background: "transparent",
border: 0,
color: "inherit",
display: "inline",
fontSize: theme.fontSizes.sm,
lineHeight: "inherit",
margin: 0,
overflowX: "auto",
padding: 0,
whiteSpace: "pre",
wordBreak: "normal",
wordWrap: "normal",
...codeLink,
})

export const StyledCode = styled.code(({ theme }) => ({
...codeBlockStyle(theme),
}))

/*
This is the default prism.js theme for JavaScript, CSS and HTML, but
Expand All @@ -23,11 +62,24 @@ import styled from "@emotion/styled"
See https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript
*/
export const StyledPre = styled.pre(({ theme }) => ({
background: theme.colors.codeHighlightColor,
borderRadius: theme.radii.default,
color: theme.colors.bodyText,
display: "block",
// Remove browser default top margin
margin: 0,
// Disable auto-hiding scrollbar in legacy Edge to avoid overlap,
// making it impossible to interact with the content
msOverflowStyle: "scrollbar",

// Don't allow content to break outside
overflow: "auto",
// Add padding
padding: theme.spacing.lg,
// Add padding to the right to account for the copy button
paddingRight: theme.iconSizes.threeXL,
color: theme.colors.bodyText,
borderRadius: theme.radii.default,

code: { ...codeBlockStyle(theme) },

// The token can consist of many lines, e.g. a triple-quote string, so
// we need to make sure that the color is not overwritten.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import React, { ReactElement } from "react"

import ErrorElement from "@streamlit/lib/src/components/shared/ErrorElement"
import { StyledInlineCode } from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"

import {
MapboxTokenFetchingError,
Expand All @@ -42,8 +43,9 @@ const MapboxTokenError = ({
message={
<>
<p>
To use <code>st.{deltaType}</code> or <code>st.map</code> you
need to set up a Mapbox access token.
To use <StyledInlineCode>st.{deltaType}</StyledInlineCode> or{" "}
<StyledInlineCode>st.map</StyledInlineCode> you need to set up a
Mapbox access token.
</p>

<p>
Expand All @@ -54,9 +56,9 @@ const MapboxTokenError = ({

<p>
Once you have a token, just set it using the Streamlit config
option <code>mapbox.token</code> and don't forget to restart your
Streamlit server at this point if it's still running, then reload
this tab.
option <StyledInlineCode>mapbox.token</StyledInlineCode> and
don't forget to restart your Streamlit server at this point if
it's still running, then reload this tab.
</p>

<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import AlertContainer, {
} from "@streamlit/lib/src/components/shared/AlertContainer"
import StreamlitMarkdown from "@streamlit/lib/src/components/shared/StreamlitMarkdown"
import { Exception as ExceptionProto } from "@streamlit/lib/src/proto"
import { StyledCode } from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"

import {
StyledMessageType,
Expand Down Expand Up @@ -83,13 +84,13 @@ function StackTrace({ stackTrace }: Readonly<StackTraceProps>): ReactElement {
<>
<StyledStackTraceTitle>Traceback:</StyledStackTraceTitle>
<StyledStackTrace>
<code>
<StyledCode>
{stackTrace.map((row: string, index: number) => (
<StyledStackTraceRow key={index} data-testid="stExceptionTraceRow">
{row}
</StyledStackTraceRow>
))}
</code>
</StyledCode>
</StyledStackTrace>
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ export const StyledStackTrace = styled.pre(({ theme }) => ({
color: "inherit",
fontSize: theme.fontSizes.sm,
backgroundColor: theme.colors.transparent,

code: {
color: "inherit",
},
overflowX: "auto",
margin: `0 0 ${theme.spacing.lg} 0`,
}))
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import React, { ReactElement } from "react"
import AlertContainer, {
Kind,
} from "@streamlit/lib/src/components/shared/AlertContainer"
import { StyledCode } from "@streamlit/lib/src/components/elements/CodeBlock/styled-components"

import { StyledPreError } from "./styled-components"

Expand Down Expand Up @@ -50,7 +51,7 @@ function ErrorElement(props: ErrorElementProps): ReactElement {
{message}
{stack ? (
<StyledPreError data-testid="stErrorElementStack">
<code>{cleanedStack}</code>
<StyledCode>{cleanedStack}</StyledCode>
</StyledPreError>
) : null}
</AlertContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ export const StyledPreError = styled.pre(({ theme }) => ({
wordWrap: "break-word",
color: "inherit",
fontSize: theme.fontSizes.sm,
overflowX: "auto",
margin: `0 0 ${theme.spacing.lg} 0`,
}))
Loading

0 comments on commit 8d7c55e

Please sign in to comment.