forked from streamlit/streamlit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add feedback widget (streamlit#8915)
## Describe your changes Add a native `st.feedback` widget that shows one of the following options: `thumbs`, `faces`, and `stars`. It is built on top of a more generic `button_group` widget that can be used in the future for other projects; in follow-up work we should start to share more code with `multiselect` and `selectbox` (mainly web app and Python unit tests). The widget returns a sentiment value (positive integer), starting at `0` for the worst sentiment up to `n-1` where `n` is the number of feedback options (`n[thumbs] = 2`, `n[faces | stars] = 5`. --- **Contribution License Agreement** By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
- Loading branch information
Showing
48 changed files
with
2,175 additions
and
155 deletions.
There are no files selected for viewing
Binary file added
BIN
+2.52 KB
...__snapshots__/linux/st_feedback_test/st_feedback-faces[dark_theme-chromium].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+3.13 KB
.../__snapshots__/linux/st_feedback_test/st_feedback-faces[dark_theme-firefox].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+2.71 KB
...t/__snapshots__/linux/st_feedback_test/st_feedback-faces[dark_theme-webkit].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+2.39 KB
..._snapshots__/linux/st_feedback_test/st_feedback-faces[light_theme-chromium].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+3.11 KB
...__snapshots__/linux/st_feedback_test/st_feedback-faces[light_theme-firefox].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+2.57 KB
.../__snapshots__/linux/st_feedback_test/st_feedback-faces[light_theme-webkit].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.74 KB
...__snapshots__/linux/st_feedback_test/st_feedback-stars[dark_theme-chromium].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+2 KB
.../__snapshots__/linux/st_feedback_test/st_feedback-stars[dark_theme-firefox].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.74 KB
...t/__snapshots__/linux/st_feedback_test/st_feedback-stars[dark_theme-webkit].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.64 KB
..._snapshots__/linux/st_feedback_test/st_feedback-stars[light_theme-chromium].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.97 KB
...__snapshots__/linux/st_feedback_test/st_feedback-stars[light_theme-firefox].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.65 KB
.../__snapshots__/linux/st_feedback_test/st_feedback-stars[light_theme-webkit].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.4 KB
..._snapshots__/linux/st_feedback_test/st_feedback-thumbs[dark_theme-chromium].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.79 KB
...__snapshots__/linux/st_feedback_test/st_feedback-thumbs[dark_theme-firefox].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.46 KB
.../__snapshots__/linux/st_feedback_test/st_feedback-thumbs[dark_theme-webkit].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.3 KB
...snapshots__/linux/st_feedback_test/st_feedback-thumbs[light_theme-chromium].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.75 KB
..._snapshots__/linux/st_feedback_test/st_feedback-thumbs[light_theme-firefox].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.37 KB
...__snapshots__/linux/st_feedback_test/st_feedback-thumbs[light_theme-webkit].png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# 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 time | ||
|
||
import streamlit as st | ||
|
||
st.feedback() | ||
st.feedback( | ||
"faces", | ||
key="faces_feedback", | ||
on_change=lambda: st.write(f"Faces sentiment: {st.session_state.faces_feedback}"), | ||
) | ||
sentiment = st.feedback("stars") | ||
st.write(f"Star sentiment: {sentiment}") | ||
|
||
|
||
sentiment = st.feedback("stars", disabled=True, key="disabled_feedback") | ||
st.write("feedback-disabled:", str(sentiment)) | ||
|
||
with st.form(key="my_form", clear_on_submit=True): | ||
sentiment = st.feedback() | ||
st.form_submit_button("Submit") | ||
|
||
st.write("feedback-in-form:", str(sentiment)) | ||
|
||
|
||
@st.experimental_fragment() | ||
def test_fragment(): | ||
sentiment = st.feedback(key="fragment_feedback") | ||
st.write("feedback-in-fragment:", str(sentiment)) | ||
|
||
|
||
test_fragment() | ||
|
||
|
||
if st.button("Create some elements to unmount component"): | ||
for _ in range(3): | ||
# The sleep here is needed, because it won't unmount the | ||
# component if this is too fast. | ||
time.sleep(1) | ||
st.write("Another element") | ||
|
||
sentiment = st.feedback(key="after_sleep_feedback") | ||
st.write("feedback-after-sleep:", str(sentiment)) | ||
|
||
|
||
if "runs" not in st.session_state: | ||
st.session_state.runs = 0 | ||
st.session_state.runs += 1 | ||
st.write("Runs:", st.session_state.runs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# 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 re | ||
|
||
from playwright.sync_api import Locator, Page, expect | ||
|
||
from e2e_playwright.conftest import ImageCompareFunction, wait_for_app_run | ||
from e2e_playwright.shared.app_utils import click_button, get_markdown | ||
|
||
|
||
def get_button_group(app: Page, index: int) -> Locator: | ||
return app.get_by_test_id("stButtonGroup").nth(index) | ||
|
||
|
||
def get_feedback_icon_buttons(locator: Locator, type: str) -> Locator: | ||
return locator.get_by_test_id( | ||
re.compile("baseButton-borderlessIcon(Active)?") | ||
).filter(has_text=type) | ||
|
||
|
||
def get_feedback_icon_button(locator: Locator, type: str, index: int = 0) -> Locator: | ||
return get_feedback_icon_buttons(locator, type).nth(index) | ||
|
||
|
||
def test_click_thumbsup_and_take_snapshot( | ||
themed_app: Page, assert_snapshot: ImageCompareFunction | ||
): | ||
thumbs = get_button_group(themed_app, 0) | ||
get_feedback_icon_button(thumbs, "thumb_up").click() | ||
wait_for_app_run(themed_app) | ||
assert_snapshot(thumbs, name="st_feedback-thumbs") | ||
|
||
|
||
def test_clicking_on_faces_shows_sentiment_via_on_change_callback_and_take_snapshot( | ||
themed_app: Page, assert_snapshot: ImageCompareFunction | ||
): | ||
faces = get_button_group(themed_app, 1) | ||
get_feedback_icon_button(faces, "sentiment_satisfied").click() | ||
wait_for_app_run(themed_app) | ||
text = get_markdown(themed_app, "Faces sentiment: 3") | ||
expect(text).to_be_attached() | ||
assert_snapshot(faces, name="st_feedback-faces") | ||
|
||
|
||
def test_clicking_on_stars_shows_sentiment_and_take_snapshot( | ||
themed_app: Page, assert_snapshot: ImageCompareFunction | ||
): | ||
stars = get_button_group(themed_app, 2) | ||
get_feedback_icon_button(stars, "star", 3).click() | ||
wait_for_app_run(themed_app) | ||
text = get_markdown(themed_app, "Star sentiment: 3") | ||
expect(text).to_be_attached() | ||
assert_snapshot(stars, name="st_feedback-stars") | ||
|
||
|
||
def test_feedback_buttons_are_disabled(app: Page): | ||
"""Test that feedback buttons are disabled when `disabled=True` and that | ||
they cannot be interacted with.""" | ||
|
||
stars = get_button_group(app, 3) | ||
star_buttons = get_feedback_icon_buttons(stars, "star") | ||
for star_button in star_buttons.all(): | ||
expect(star_button).to_have_js_property("disabled", True) | ||
selected_button = star_buttons.nth(4) | ||
selected_button.click(force=True) | ||
expect(selected_button).not_to_have_css( | ||
"background-color", re.compile("rgb\\(\\d+, \\d+, \\d+\\)") | ||
) | ||
text = get_markdown(app, "feedback-disabled: None") | ||
expect(text).to_be_attached() | ||
|
||
|
||
def test_feedback_works_in_forms(app: Page): | ||
expect(app.get_by_text("feedback-in-form: None")).to_be_visible() | ||
thumbs = get_button_group(app, 4) | ||
get_feedback_icon_button(thumbs, "thumb_up").click() | ||
expect(app.get_by_text("feedback-in-form: None")).to_be_visible() | ||
app.get_by_test_id("baseButton-secondaryFormSubmit").click() | ||
wait_for_app_run(app) | ||
|
||
text = get_markdown(app, "feedback-in-form: 1") | ||
expect(text).to_be_attached() | ||
|
||
|
||
def test_feedback_works_with_fragments(app: Page): | ||
expect(app.get_by_text("Runs: 1")).to_be_visible() | ||
expect(app.get_by_text("feedback-in-fragment: None")).to_be_visible() | ||
thumbs = get_button_group(app, 5) | ||
get_feedback_icon_button(thumbs, "thumb_up").click() | ||
wait_for_app_run(app) | ||
expect(app.get_by_text("feedback-in-fragment: 1")).to_be_visible() | ||
expect(app.get_by_text("Runs: 1")).to_be_visible() | ||
|
||
|
||
def test_feedback_remount_keep_value(app: Page): | ||
"""Test that `st.feedback` remounts correctly without resetting value.""" | ||
expect(app.get_by_text("feedback-after-sleep: None")).to_be_visible() | ||
|
||
thumbs = get_button_group(app, 6) | ||
selected_button = get_feedback_icon_button(thumbs, "thumb_up") | ||
selected_button.click() | ||
wait_for_app_run(app) | ||
expect(app.get_by_text("feedback-after-sleep: 1")).to_be_visible() | ||
expect(selected_button).to_have_css( | ||
"background-color", re.compile("rgb\\(\\d+, \\d+, \\d+\\)") | ||
) | ||
click_button(app, "Create some elements to unmount component") | ||
expect(selected_button).to_have_css( | ||
"background-color", re.compile("rgb\\(\\d+, \\d+, \\d+\\)") | ||
) | ||
expect(app.get_by_text("feedback-after-sleep: 1")).to_be_visible() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.