streamlit 1.51.0__py3-none-any.whl → 1.52.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/__init__.py +1 -0
- streamlit/commands/execution_control.py +89 -14
- streamlit/components/v1/component_arrow.py +7 -7
- streamlit/components/v2/__init__.py +59 -3
- streamlit/components/v2/bidi_component/main.py +161 -13
- streamlit/components/v2/bidi_component/serialization.py +13 -6
- streamlit/components/v2/component_manager.py +11 -3
- streamlit/components/v2/component_registry.py +18 -1
- streamlit/components/v2/types.py +2 -2
- streamlit/connections/snowflake_connection.py +1 -1
- streamlit/connections/snowpark_connection.py +1 -1
- streamlit/dataframe_util.py +18 -18
- streamlit/delta_generator.py +7 -0
- streamlit/delta_generator_singletons.py +8 -14
- streamlit/elements/alert.py +16 -0
- streamlit/elements/arrow.py +36 -6
- streamlit/elements/bokeh_chart.py +10 -78
- streamlit/elements/code.py +2 -2
- streamlit/elements/deck_gl_json_chart.py +1 -1
- streamlit/elements/exception.py +1 -1
- streamlit/elements/form.py +27 -0
- streamlit/elements/heading.py +60 -5
- streamlit/elements/html.py +13 -2
- streamlit/elements/image.py +1 -1
- streamlit/elements/layouts.py +28 -22
- streamlit/elements/lib/built_in_chart_utils.py +49 -16
- streamlit/elements/lib/color_util.py +1 -1
- streamlit/elements/lib/column_config_utils.py +6 -5
- streamlit/elements/lib/layout_utils.py +50 -0
- streamlit/elements/lib/pandas_styler_utils.py +17 -9
- streamlit/elements/lib/shortcut_utils.py +152 -0
- streamlit/elements/markdown.py +50 -3
- streamlit/elements/metric.py +31 -1
- streamlit/elements/plotly_chart.py +75 -6
- streamlit/elements/spinner.py +1 -1
- streamlit/elements/text.py +20 -3
- streamlit/elements/toast.py +2 -0
- streamlit/elements/vega_charts.py +17 -1
- streamlit/elements/widgets/audio_input.py +8 -7
- streamlit/elements/widgets/button.py +279 -40
- streamlit/elements/widgets/button_group.py +27 -2
- streamlit/elements/widgets/camera_input.py +1 -1
- streamlit/elements/widgets/chat.py +300 -42
- streamlit/elements/widgets/color_picker.py +7 -0
- streamlit/elements/widgets/data_editor.py +68 -28
- streamlit/elements/widgets/file_uploader.py +4 -1
- streamlit/elements/widgets/number_input.py +2 -0
- streamlit/elements/widgets/text_widgets.py +2 -0
- streamlit/elements/widgets/time_widgets.py +581 -9
- streamlit/errors.py +22 -0
- streamlit/git_util.py +1 -1
- streamlit/navigation/page.py +7 -0
- streamlit/net_util.py +2 -2
- streamlit/proto/Alert_pb2.pyi +3 -3
- streamlit/proto/AppPage_pb2.pyi +7 -1
- streamlit/proto/ArrowData_pb2.pyi +7 -1
- streamlit/proto/ArrowNamedDataSet_pb2.pyi +7 -1
- streamlit/proto/ArrowVegaLiteChart_pb2.pyi +7 -1
- streamlit/proto/Arrow_pb2.py +10 -10
- streamlit/proto/Arrow_pb2.pyi +19 -12
- streamlit/proto/AudioInput_pb2.pyi +7 -1
- streamlit/proto/Audio_pb2.pyi +7 -1
- streamlit/proto/AuthRedirect_pb2.pyi +7 -1
- streamlit/proto/AutoRerun_pb2.pyi +7 -1
- streamlit/proto/BackMsg_pb2.py +4 -2
- streamlit/proto/BackMsg_pb2.pyi +34 -4
- streamlit/proto/Balloons_pb2.pyi +7 -1
- streamlit/proto/BidiComponent_pb2.pyi +10 -4
- streamlit/proto/Block_pb2.pyi +35 -35
- streamlit/proto/BokehChart_pb2.pyi +7 -1
- streamlit/proto/ButtonGroup_pb2.pyi +9 -9
- streamlit/proto/Button_pb2.py +2 -2
- streamlit/proto/Button_pb2.pyi +11 -2
- streamlit/proto/CameraInput_pb2.pyi +7 -1
- streamlit/proto/ChatInput_pb2.py +6 -6
- streamlit/proto/ChatInput_pb2.pyi +18 -6
- streamlit/proto/Checkbox_pb2.pyi +3 -3
- streamlit/proto/ClientState_pb2.pyi +10 -4
- streamlit/proto/Code_pb2.pyi +7 -1
- streamlit/proto/ColorPicker_pb2.pyi +7 -1
- streamlit/proto/Common_pb2.py +3 -3
- streamlit/proto/Common_pb2.pyi +35 -23
- streamlit/proto/Components_pb2.pyi +19 -13
- streamlit/proto/DataFrame_pb2.pyi +55 -49
- streamlit/proto/DateInput_pb2.pyi +7 -1
- streamlit/proto/DateTimeInput_pb2.py +28 -0
- streamlit/proto/DateTimeInput_pb2.pyi +92 -0
- streamlit/proto/DeckGlJsonChart_pb2.pyi +3 -3
- streamlit/proto/Delta_pb2.pyi +7 -1
- streamlit/proto/DocString_pb2.pyi +10 -4
- streamlit/proto/DownloadButton_pb2.py +2 -2
- streamlit/proto/DownloadButton_pb2.pyi +16 -2
- streamlit/proto/Element_pb2.py +5 -3
- streamlit/proto/Element_pb2.pyi +23 -5
- streamlit/proto/Empty_pb2.pyi +7 -1
- streamlit/proto/Exception_pb2.pyi +7 -1
- streamlit/proto/Favicon_pb2.pyi +7 -1
- streamlit/proto/FileUploader_pb2.pyi +7 -1
- streamlit/proto/ForwardMsg_pb2.py +12 -10
- streamlit/proto/ForwardMsg_pb2.pyi +42 -15
- streamlit/proto/GapSize_pb2.pyi +4 -4
- streamlit/proto/GitInfo_pb2.pyi +3 -3
- streamlit/proto/GraphVizChart_pb2.pyi +7 -1
- streamlit/proto/Heading_pb2.pyi +7 -1
- streamlit/proto/HeightConfig_pb2.pyi +7 -1
- streamlit/proto/Html_pb2.py +2 -2
- streamlit/proto/Html_pb2.pyi +11 -2
- streamlit/proto/IFrame_pb2.pyi +7 -1
- streamlit/proto/Image_pb2.pyi +10 -4
- streamlit/proto/Json_pb2.pyi +7 -1
- streamlit/proto/LabelVisibilityMessage_pb2.pyi +3 -3
- streamlit/proto/LinkButton_pb2.py +2 -2
- streamlit/proto/LinkButton_pb2.pyi +15 -2
- streamlit/proto/Logo_pb2.pyi +7 -1
- streamlit/proto/Markdown_pb2.pyi +3 -3
- streamlit/proto/Metric_pb2.pyi +7 -7
- streamlit/proto/MetricsEvent_pb2.pyi +10 -4
- streamlit/proto/MultiSelect_pb2.pyi +7 -1
- streamlit/proto/NamedDataSet_pb2.pyi +7 -1
- streamlit/proto/Navigation_pb2.pyi +3 -3
- streamlit/proto/NewSession_pb2.pyi +40 -40
- streamlit/proto/NumberInput_pb2.pyi +3 -3
- streamlit/proto/PageConfig_pb2.pyi +7 -7
- streamlit/proto/PageInfo_pb2.pyi +7 -1
- streamlit/proto/PageLink_pb2.py +2 -2
- streamlit/proto/PageLink_pb2.pyi +11 -2
- streamlit/proto/PageNotFound_pb2.pyi +7 -1
- streamlit/proto/PageProfile_pb2.pyi +13 -7
- streamlit/proto/PagesChanged_pb2.pyi +7 -1
- streamlit/proto/ParentMessage_pb2.pyi +7 -1
- streamlit/proto/PlotlyChart_pb2.pyi +6 -6
- streamlit/proto/Progress_pb2.pyi +7 -1
- streamlit/proto/Radio_pb2.pyi +7 -1
- streamlit/proto/RootContainer_pb2.pyi +1 -1
- streamlit/proto/Selectbox_pb2.pyi +7 -1
- streamlit/proto/SessionEvent_pb2.pyi +7 -1
- streamlit/proto/SessionStatus_pb2.pyi +7 -1
- streamlit/proto/Skeleton_pb2.pyi +3 -3
- streamlit/proto/Slider_pb2.pyi +5 -5
- streamlit/proto/Snow_pb2.pyi +7 -1
- streamlit/proto/Space_pb2.pyi +7 -1
- streamlit/proto/Spinner_pb2.pyi +7 -1
- streamlit/proto/TextAlignmentConfig_pb2.py +29 -0
- streamlit/proto/TextAlignmentConfig_pb2.pyi +68 -0
- streamlit/proto/TextArea_pb2.pyi +7 -1
- streamlit/proto/TextInput_pb2.pyi +3 -3
- streamlit/proto/Text_pb2.pyi +7 -1
- streamlit/proto/TimeInput_pb2.pyi +7 -1
- streamlit/proto/Toast_pb2.pyi +7 -1
- streamlit/proto/VegaLiteChart_pb2.pyi +7 -1
- streamlit/proto/Video_pb2.pyi +6 -6
- streamlit/proto/WidgetStates_pb2.pyi +10 -4
- streamlit/proto/WidthConfig_pb2.pyi +7 -1
- streamlit/proto/openmetrics_data_model_pb2.pyi +52 -52
- streamlit/runtime/app_session.py +38 -1
- streamlit/runtime/caching/cache_data_api.py +1 -1
- streamlit/runtime/caching/cache_resource_api.py +2 -2
- streamlit/runtime/caching/cache_utils.py +1 -1
- streamlit/runtime/caching/hashing.py +1 -1
- streamlit/runtime/download_data_util.py +53 -0
- streamlit/runtime/forward_msg_queue.py +1 -0
- streamlit/runtime/media_file_manager.py +178 -2
- streamlit/runtime/metrics_util.py +87 -3
- streamlit/runtime/scriptrunner/script_runner.py +3 -1
- streamlit/runtime/state/query_params.py +80 -29
- streamlit/runtime/state/session_state.py +2 -2
- streamlit/static/index.html +1 -1
- streamlit/static/manifest.json +530 -229
- streamlit/static/static/js/{ErrorOutline.esm.YoJdlW1p.js → ErrorOutline.esm.ZJDbmVTx.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.Ddx8VEYy.js → FileDownload.esm.Dx0vI3vH.js} +1 -1
- streamlit/static/static/js/{FileHelper.90EtOmj9.js → FileHelper.B7Ero7qQ.js} +3 -3
- streamlit/static/static/js/{FormClearHelper.BB1Km6eP.js → FormClearHelper.CG2XN1_g.js} +1 -1
- streamlit/static/static/js/IFrameUtil.DefezniK.js +1 -0
- streamlit/static/static/js/InputInstructions.Cj5-1zf6.js +1 -0
- streamlit/static/static/js/Particles.BfWfv0Aw.js +1 -0
- streamlit/static/static/js/{ProgressBar.DLY8H6nE.js → ProgressBar.CGQ8OgfO.js} +2 -2
- streamlit/static/static/js/StreamlitSyntaxHighlighter.DTKLpwhl.js +20 -0
- streamlit/static/static/js/{Toolbar.D8nHCkuz.js → Toolbar.B2qFUmd9.js} +1 -1
- streamlit/static/static/js/_arrayIncludes.B19Iyn2B.js +1 -0
- streamlit/static/static/js/_baseIndexOf.BTknn6Gb.js +1 -0
- streamlit/static/static/js/{base-input.CJGiNqed.js → base-input.o9tL8MDP.js} +4 -4
- streamlit/static/static/js/{checkbox.Cpdd482O.js → checkbox.0BeV1IBL.js} +1 -1
- streamlit/static/static/js/{createSuper.CuQIogbW.js → createSuper.RBO59fEm.js} +1 -1
- streamlit/static/static/js/data-grid-overlay-editor.CiTkUy0t.js +1 -0
- streamlit/static/static/js/{downloader.CN0K7xlu.js → downloader.DwNZg3Mw.js} +1 -1
- streamlit/static/static/js/embed.XT9xNd3F.js +195 -0
- streamlit/static/static/js/{es6.BJcsVXQ0.js → es6.x9KsYQg-.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.XzUvQqcZ.js → iframeResizer.contentWindow.ZVXpMPi0.js} +1 -1
- streamlit/static/static/js/index.5VPOamri.js +1 -0
- streamlit/static/static/js/index.8HslT92O.js +14 -0
- streamlit/static/static/js/index.AnXMIBz3.js +7 -0
- streamlit/static/static/js/index.B0yp3bM1.js +6 -0
- streamlit/static/static/js/index.B1fRb5wF.js +1 -0
- streamlit/static/static/js/index.B527JZdO.js +3 -0
- streamlit/static/static/js/index.BHgV-yW4.js +1 -0
- streamlit/static/static/js/index.BQr-XwGV.js +1 -0
- streamlit/static/static/js/index.BTtmaLDB.js +1 -0
- streamlit/static/static/js/index.BWB_91TA.js +1 -0
- streamlit/static/static/js/index.BfEKaEmw.js +1 -0
- streamlit/static/static/js/index.BfXjTO8b.js +1 -0
- streamlit/static/static/js/index.Bjy4NRu9.js +3 -0
- streamlit/static/static/js/index.Bu5JWpT_.js +1 -0
- streamlit/static/static/js/index.BuCx76ZV.js +1 -0
- streamlit/static/static/js/index.BxjzhVUb.js +2 -0
- streamlit/static/static/js/index.By55VdPY.js +1 -0
- streamlit/static/static/js/index.CF5MxTbK.js +1 -0
- streamlit/static/static/js/index.CLmq_z9K.js +1 -0
- streamlit/static/static/js/index.CNH4rdSz.js +1 -0
- streamlit/static/static/js/{index.D3GPA5k4.js → index.CTgm_-jO.js} +9 -40
- streamlit/static/static/js/index.C_rK-Swb.js +188 -0
- streamlit/static/static/js/index.CjozwSzS.js +1 -0
- streamlit/static/static/js/{index.DOFlg3dS.js → index.CkGVt6-G.js} +1 -1
- streamlit/static/static/js/index.CuvXOyER.js +2 -0
- streamlit/static/static/js/{index.B_dWA3vd.js → index.CyUHWoCC.js} +2 -2
- streamlit/static/static/js/index.CyroQtI4.js +2 -0
- streamlit/static/static/js/index.D6HmkoDm.js +263 -0
- streamlit/static/static/js/index.DAqCNvsO.js +1 -0
- streamlit/static/static/js/index.DB_w_CZQ.js +1 -0
- streamlit/static/static/js/index.DBalctjj.js +2 -0
- streamlit/static/static/js/index.DK0RFJUG.js +11 -0
- streamlit/static/static/js/index.DMxc2XFp.js +151 -0
- streamlit/static/static/js/index.DO5utP74.js +2 -0
- streamlit/static/static/js/index.DS7lf09n.js +1 -0
- streamlit/static/static/js/index.DWexTVLY.js +1 -0
- streamlit/static/static/js/index.DXxnU5ej.js +1 -0
- streamlit/static/static/js/index.DcU3uDvB.js +2 -0
- streamlit/static/static/js/index.DlltaH7J.js +1 -0
- streamlit/static/static/js/index.DpNTZz82.js +27 -0
- streamlit/static/static/js/index.Dr9HIhQw.js +1 -0
- streamlit/static/static/js/index.DsgAU5lc.js +1 -0
- streamlit/static/static/js/{index.DPUXkcQL.js → index.KfXqjDYy.js} +1 -1
- streamlit/static/static/js/index.PaidgjCs.js +1 -0
- streamlit/static/static/js/index.RJZuWCGA.js +1 -0
- streamlit/static/static/js/{index.CxIUUfab.js → index.hbeqcRTn.js} +53 -122
- streamlit/static/static/js/index.q5hIQwAY.js +1 -0
- streamlit/static/static/js/index.rORSX6IW.js +1 -0
- streamlit/static/static/js/index.uSX757_v.js +1 -0
- streamlit/static/static/js/index.x_QRaLMd.js +1 -0
- streamlit/static/static/js/{input.D4MN_FzN.js → input.D5oh9-aB.js} +2 -2
- streamlit/static/static/js/main.q9oGOg0H.js +13 -0
- streamlit/static/static/js/{memory.DrZjtdGT.js → memory.5kCSFUJS.js} +1 -1
- streamlit/static/static/js/moment.C3j7ZXd7.js +4 -0
- streamlit/static/static/js/number-overlay-editor.Cn_LsK8N.js +9 -0
- streamlit/static/static/js/pandasStylerUtils.BqhXt51_.js +1 -0
- streamlit/static/static/js/{possibleConstructorReturn.exeeJQEP.js → possibleConstructorReturn.DD9NK1Z8.js} +1 -1
- streamlit/static/static/js/{sandbox.ClO3IuUr.js → sandbox.DACSyz29.js} +1 -1
- streamlit/static/static/js/styled-components.C3R090At.js +1 -0
- streamlit/static/static/js/threshold.Q1mXg5rX.js +1 -0
- streamlit/static/static/js/throttle.B0GR3Iyz.js +1 -0
- streamlit/static/static/js/{timepicker.DAhu-vcF.js → timepicker.BdhzPxrv.js} +1 -1
- streamlit/static/static/js/timer.C2hYhUse.js +1 -0
- streamlit/static/static/js/{toConsumableArray.DNbljYEC.js → toConsumableArray.Db2pdqM2.js} +1 -1
- streamlit/static/static/js/uniqueId.CtqIr-Yh.js +1 -0
- streamlit/static/static/js/urls.BwSlolu9.js +1 -0
- streamlit/static/static/js/{useBasicWidgetState.D6sOH6oI.js → useBasicWidgetState.Bfp6TnSw.js} +1 -1
- streamlit/static/static/js/useIntlLocale.hRV75Xgj.js +12 -0
- streamlit/static/static/js/{useTextInputAutoExpand.4u3_GcuN.js → useTextInputAutoExpand.QepX7n8Y.js} +1 -1
- streamlit/static/static/js/useUpdateUiValue.DHx8TzX6.js +1 -0
- streamlit/static/static/js/useWaveformController.WxVzpzEX.js +1 -0
- streamlit/static/static/js/value.B4vHRSi7.js +1 -0
- streamlit/static/static/js/withCalculatedWidth.DcKeRSWJ.js +1 -0
- streamlit/static/static/js/withFullScreenWrapper.CrHddARq.js +1 -0
- streamlit/string_util.py +8 -1
- streamlit/testing/v1/app_test.py +15 -0
- streamlit/testing/v1/element_tree.py +62 -0
- streamlit/web/bootstrap.py +24 -0
- streamlit/web/server/oauth_authlib_routes.py +5 -2
- streamlit/web/server/upload_file_request_handler.py +16 -0
- {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/METADATA +9 -5
- {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/RECORD +274 -239
- streamlit/static/static/js/InputInstructions.jhH15PqV.js +0 -1
- streamlit/static/static/js/Particles.DUsputn1.js +0 -1
- streamlit/static/static/js/data-grid-overlay-editor.2Ufgxc6y.js +0 -1
- streamlit/static/static/js/index.B1ZQh4P1.js +0 -1
- streamlit/static/static/js/index.BKstZk0M.js +0 -27
- streamlit/static/static/js/index.BMcFsUee.js +0 -1
- streamlit/static/static/js/index.BR-IdcTb.js +0 -2
- streamlit/static/static/js/index.BgnZEMVh.js +0 -1
- streamlit/static/static/js/index.BohqXifI.js +0 -1
- streamlit/static/static/js/index.Br5nxKNj.js +0 -2
- streamlit/static/static/js/index.BrIKVbNc.js +0 -3
- streamlit/static/static/js/index.BtWUPzle.js +0 -1
- streamlit/static/static/js/index.C0RLraek.js +0 -1
- streamlit/static/static/js/index.CAIjskgG.js +0 -1
- streamlit/static/static/js/index.CAj-7vWz.js +0 -949
- streamlit/static/static/js/index.CMtEit2O.js +0 -1
- streamlit/static/static/js/index.CkRlykEE.js +0 -12
- streamlit/static/static/js/index.CmN3FXfI.js +0 -1617
- streamlit/static/static/js/index.CwbFI1_-.js +0 -1
- streamlit/static/static/js/index.D2KPNy7e.js +0 -1
- streamlit/static/static/js/index.DGAh7DMq.js +0 -1
- streamlit/static/static/js/index.DKb_NvmG.js +0 -197
- streamlit/static/static/js/index.DMqgUYKq.js +0 -1
- streamlit/static/static/js/index.DX1xY89g.js +0 -1
- streamlit/static/static/js/index.DYATBCsq.js +0 -2
- streamlit/static/static/js/index.DaSmGJ76.js +0 -3
- streamlit/static/static/js/index.Dd7bMeLP.js +0 -1
- streamlit/static/static/js/index.DjmmgI5U.js +0 -1
- streamlit/static/static/js/index.Dq56CyM2.js +0 -1
- streamlit/static/static/js/index.DuiXaS5_.js +0 -7
- streamlit/static/static/js/index.DvFidMLe.js +0 -2
- streamlit/static/static/js/index.DwkhC5Pc.js +0 -1
- streamlit/static/static/js/index.Q-3sFn1v.js +0 -1
- streamlit/static/static/js/index.QJ5QO9sJ.js +0 -1
- streamlit/static/static/js/index.VwTaeety.js +0 -1
- streamlit/static/static/js/index.YOqQbeX8.js +0 -1
- streamlit/static/static/js/number-overlay-editor.DRwAw1In.js +0 -9
- streamlit/static/static/js/uniqueId.oG4Gvj1v.js +0 -1
- streamlit/static/static/js/useUpdateUiValue.F2R3eTeR.js +0 -1
- streamlit/static/static/js/withFullScreenWrapper.zothJIsI.js +0 -1
- {streamlit-1.51.0.data → streamlit-1.52.0.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/WHEEL +0 -0
- {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/entry_points.txt +0 -0
- {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/top_level.txt +0 -0
streamlit/elements/heading.py
CHANGED
|
@@ -25,7 +25,7 @@ from streamlit.string_util import clean_text
|
|
|
25
25
|
|
|
26
26
|
if TYPE_CHECKING:
|
|
27
27
|
from streamlit.delta_generator import DeltaGenerator
|
|
28
|
-
from streamlit.elements.lib.layout_utils import Width
|
|
28
|
+
from streamlit.elements.lib.layout_utils import TextAlignment, Width
|
|
29
29
|
from streamlit.type_util import SupportsStr
|
|
30
30
|
|
|
31
31
|
|
|
@@ -49,6 +49,7 @@ class HeadingMixin:
|
|
|
49
49
|
help: str | None = None,
|
|
50
50
|
divider: Divider = False,
|
|
51
51
|
width: Width = "stretch",
|
|
52
|
+
text_alignment: TextAlignment = "left",
|
|
52
53
|
) -> DeltaGenerator:
|
|
53
54
|
"""Display text in header formatting.
|
|
54
55
|
|
|
@@ -97,6 +98,22 @@ class HeadingMixin:
|
|
|
97
98
|
the parent container, the width of the element matches the width
|
|
98
99
|
of the parent container.
|
|
99
100
|
|
|
101
|
+
text_alignment : "left", "center", "right", or "justify"
|
|
102
|
+
The horizontal alignment of the text within the element. This can
|
|
103
|
+
be one of the following:
|
|
104
|
+
|
|
105
|
+
- ``"left"`` (default): Text is aligned to the left edge.
|
|
106
|
+
- ``"center"``: Text is centered.
|
|
107
|
+
- ``"right"``: Text is aligned to the right edge.
|
|
108
|
+
- ``"justify"``: Text is justified (stretched to fill the available
|
|
109
|
+
width with the last line left-aligned).
|
|
110
|
+
|
|
111
|
+
.. note::
|
|
112
|
+
For text alignment to have a visible effect, the element's
|
|
113
|
+
width must be wider than its content. If you use
|
|
114
|
+
``width="content"`` with short text, the alignment may not be
|
|
115
|
+
noticeable.
|
|
116
|
+
|
|
100
117
|
Examples
|
|
101
118
|
--------
|
|
102
119
|
>>> import streamlit as st
|
|
@@ -115,7 +132,7 @@ class HeadingMixin:
|
|
|
115
132
|
|
|
116
133
|
"""
|
|
117
134
|
validate_width(width, allow_content=True)
|
|
118
|
-
layout_config = LayoutConfig(width=width)
|
|
135
|
+
layout_config = LayoutConfig(width=width, text_alignment=text_alignment)
|
|
119
136
|
|
|
120
137
|
return self.dg._enqueue(
|
|
121
138
|
"heading",
|
|
@@ -138,6 +155,7 @@ class HeadingMixin:
|
|
|
138
155
|
help: str | None = None,
|
|
139
156
|
divider: Divider = False,
|
|
140
157
|
width: Width = "stretch",
|
|
158
|
+
text_alignment: TextAlignment = "left",
|
|
141
159
|
) -> DeltaGenerator:
|
|
142
160
|
"""Display text in subheader formatting.
|
|
143
161
|
|
|
@@ -186,6 +204,22 @@ class HeadingMixin:
|
|
|
186
204
|
the parent container, the width of the element matches the width
|
|
187
205
|
of the parent container.
|
|
188
206
|
|
|
207
|
+
text_alignment : "left", "center", "right", or "justify"
|
|
208
|
+
The horizontal alignment of the text within the element. This can
|
|
209
|
+
be one of the following:
|
|
210
|
+
|
|
211
|
+
- ``"left"`` (default): Text is aligned to the left edge.
|
|
212
|
+
- ``"center"``: Text is centered.
|
|
213
|
+
- ``"right"``: Text is aligned to the right edge.
|
|
214
|
+
- ``"justify"``: Text is justified (stretched to fill the available
|
|
215
|
+
width with the last line left-aligned).
|
|
216
|
+
|
|
217
|
+
.. note::
|
|
218
|
+
For text alignment to have a visible effect, the element's
|
|
219
|
+
width must be wider than its content. If you use
|
|
220
|
+
``width="content"`` with short text, the alignment may not be
|
|
221
|
+
noticeable.
|
|
222
|
+
|
|
189
223
|
Examples
|
|
190
224
|
--------
|
|
191
225
|
>>> import streamlit as st
|
|
@@ -204,7 +238,7 @@ class HeadingMixin:
|
|
|
204
238
|
|
|
205
239
|
"""
|
|
206
240
|
validate_width(width, allow_content=True)
|
|
207
|
-
layout_config = LayoutConfig(width=width)
|
|
241
|
+
layout_config = LayoutConfig(width=width, text_alignment=text_alignment)
|
|
208
242
|
|
|
209
243
|
return self.dg._enqueue(
|
|
210
244
|
"heading",
|
|
@@ -226,6 +260,7 @@ class HeadingMixin:
|
|
|
226
260
|
*, # keyword-only arguments:
|
|
227
261
|
help: str | None = None,
|
|
228
262
|
width: Width = "stretch",
|
|
263
|
+
text_alignment: TextAlignment = "left",
|
|
229
264
|
) -> DeltaGenerator:
|
|
230
265
|
"""Display text in title formatting.
|
|
231
266
|
|
|
@@ -269,6 +304,22 @@ class HeadingMixin:
|
|
|
269
304
|
the parent container, the width of the element matches the width
|
|
270
305
|
of the parent container.
|
|
271
306
|
|
|
307
|
+
text_alignment : "left", "center", "right", or "justify"
|
|
308
|
+
The horizontal alignment of the text within the element. This can
|
|
309
|
+
be one of the following:
|
|
310
|
+
|
|
311
|
+
- ``"left"`` (default): Text is aligned to the left edge.
|
|
312
|
+
- ``"center"``: Text is centered.
|
|
313
|
+
- ``"right"``: Text is aligned to the right edge.
|
|
314
|
+
- ``"justify"``: Text is justified (stretched to fill the available
|
|
315
|
+
width with the last line left-aligned).
|
|
316
|
+
|
|
317
|
+
.. note::
|
|
318
|
+
For text alignment to have a visible effect, the element's
|
|
319
|
+
width must be wider than its content. If you use
|
|
320
|
+
``width="content"`` with short text, the alignment may not be
|
|
321
|
+
noticeable.
|
|
322
|
+
|
|
272
323
|
Examples
|
|
273
324
|
--------
|
|
274
325
|
>>> import streamlit as st
|
|
@@ -282,12 +333,15 @@ class HeadingMixin:
|
|
|
282
333
|
|
|
283
334
|
"""
|
|
284
335
|
validate_width(width, allow_content=True)
|
|
285
|
-
layout_config = LayoutConfig(width=width)
|
|
336
|
+
layout_config = LayoutConfig(width=width, text_alignment=text_alignment)
|
|
286
337
|
|
|
287
338
|
return self.dg._enqueue(
|
|
288
339
|
"heading",
|
|
289
340
|
HeadingMixin._create_heading_proto(
|
|
290
|
-
tag=HeadingProtoTag.TITLE_TAG,
|
|
341
|
+
tag=HeadingProtoTag.TITLE_TAG,
|
|
342
|
+
body=body,
|
|
343
|
+
anchor=anchor,
|
|
344
|
+
help=help,
|
|
291
345
|
),
|
|
292
346
|
layout_config=layout_config,
|
|
293
347
|
)
|
|
@@ -349,4 +403,5 @@ class HeadingMixin:
|
|
|
349
403
|
|
|
350
404
|
if help:
|
|
351
405
|
proto.help = help
|
|
406
|
+
|
|
352
407
|
return proto
|
streamlit/elements/html.py
CHANGED
|
@@ -42,6 +42,7 @@ class HtmlMixin:
|
|
|
42
42
|
body: str | Path | SupportsStr | SupportsReprHtml,
|
|
43
43
|
*, # keyword-only arguments:
|
|
44
44
|
width: Width = "stretch",
|
|
45
|
+
unsafe_allow_javascript: bool = False,
|
|
45
46
|
) -> DeltaGenerator:
|
|
46
47
|
"""Insert HTML into your app.
|
|
47
48
|
|
|
@@ -52,8 +53,10 @@ class HtmlMixin:
|
|
|
52
53
|
loading external code can increase the risk of vulnerabilities in your
|
|
53
54
|
app.
|
|
54
55
|
|
|
55
|
-
``st.html`` content is **not** iframed.
|
|
56
|
-
|
|
56
|
+
``st.html`` content is **not** iframed. By default, JavaScript is
|
|
57
|
+
ignored. To execute JavaScript contained in your HTML, set
|
|
58
|
+
``unsafe_allow_javascript=True``. Use this with caution and never pass
|
|
59
|
+
untrusted input.
|
|
57
60
|
|
|
58
61
|
Parameters
|
|
59
62
|
----------
|
|
@@ -89,6 +92,12 @@ class HtmlMixin:
|
|
|
89
92
|
the parent container, the width of the element matches the width
|
|
90
93
|
of the parent container.
|
|
91
94
|
|
|
95
|
+
unsafe_allow_javascript : bool
|
|
96
|
+
Whether to execute JavaScript contained in your HTML. If this is
|
|
97
|
+
``False`` (default), JavaScript is ignored. If this is ``True``,
|
|
98
|
+
JavaScript is executed. Use this with caution and never pass
|
|
99
|
+
untrusted input.
|
|
100
|
+
|
|
92
101
|
Example
|
|
93
102
|
-------
|
|
94
103
|
>>> import streamlit as st
|
|
@@ -136,6 +145,8 @@ class HtmlMixin:
|
|
|
136
145
|
html_proto.body = html_content
|
|
137
146
|
return self._event_dg._enqueue("html", html_proto)
|
|
138
147
|
# Otherwise, send the html to the main container as normal
|
|
148
|
+
# Only set the unsafe JS flag for non-style-only HTML content
|
|
149
|
+
html_proto.unsafe_allow_javascript = unsafe_allow_javascript
|
|
139
150
|
html_proto.body = html_content
|
|
140
151
|
return self.dg._enqueue("html", html_proto, layout_config=layout_config)
|
|
141
152
|
|
streamlit/elements/image.py
CHANGED
|
@@ -171,7 +171,7 @@ class ImageMixin:
|
|
|
171
171
|
|
|
172
172
|
show_deprecation_warning(
|
|
173
173
|
"The `use_column_width` parameter has been deprecated and will be removed "
|
|
174
|
-
"in a future release. Please utilize the `
|
|
174
|
+
"in a future release. Please utilize the `width` parameter instead."
|
|
175
175
|
)
|
|
176
176
|
if use_column_width in {"auto", "never"} or use_column_width is False:
|
|
177
177
|
width = "content"
|
streamlit/elements/layouts.py
CHANGED
|
@@ -62,7 +62,7 @@ class LayoutsMixin:
|
|
|
62
62
|
*,
|
|
63
63
|
border: bool | None = None,
|
|
64
64
|
key: Key | None = None,
|
|
65
|
-
width:
|
|
65
|
+
width: Width = "stretch",
|
|
66
66
|
height: Height = "content",
|
|
67
67
|
horizontal: bool = False,
|
|
68
68
|
horizontal_alignment: HorizontalAlignment = "left",
|
|
@@ -92,11 +92,13 @@ class LayoutsMixin:
|
|
|
92
92
|
Additionally, if ``key`` is provided, it will be used as CSS
|
|
93
93
|
class name prefixed with ``st-key-``.
|
|
94
94
|
|
|
95
|
-
width : "stretch" or int
|
|
95
|
+
width : "stretch", "content", or int
|
|
96
96
|
The width of the container. This can be one of the following:
|
|
97
97
|
|
|
98
98
|
- ``"stretch"`` (default): The width of the container matches the
|
|
99
99
|
width of the parent container.
|
|
100
|
+
- ``"content"``: The width of the container matches the width of
|
|
101
|
+
its content.
|
|
100
102
|
- An integer specifying the width in pixels: The container has a
|
|
101
103
|
fixed width. If the specified width is greater than the width of
|
|
102
104
|
the parent container, the width of the container matches the width
|
|
@@ -199,7 +201,7 @@ class LayoutsMixin:
|
|
|
199
201
|
>>>
|
|
200
202
|
>>> st.write("This is outside the container")
|
|
201
203
|
|
|
202
|
-
.. output
|
|
204
|
+
.. output::
|
|
203
205
|
https://doc-container1.streamlit.app/
|
|
204
206
|
height: 520px
|
|
205
207
|
|
|
@@ -218,7 +220,7 @@ class LayoutsMixin:
|
|
|
218
220
|
>>>
|
|
219
221
|
>>> container.write("This is inside too")
|
|
220
222
|
|
|
221
|
-
.. output
|
|
223
|
+
.. output::
|
|
222
224
|
https://doc-container2.streamlit.app/
|
|
223
225
|
height: 300px
|
|
224
226
|
|
|
@@ -236,7 +238,7 @@ class LayoutsMixin:
|
|
|
236
238
|
>>> tile = col.container(height=120)
|
|
237
239
|
>>> tile.title(":balloon:")
|
|
238
240
|
|
|
239
|
-
.. output
|
|
241
|
+
.. output::
|
|
240
242
|
https://doc-container3.streamlit.app/
|
|
241
243
|
height: 350px
|
|
242
244
|
|
|
@@ -252,7 +254,7 @@ class LayoutsMixin:
|
|
|
252
254
|
>>> with st.container(height=300):
|
|
253
255
|
>>> st.markdown(long_text)
|
|
254
256
|
|
|
255
|
-
.. output
|
|
257
|
+
.. output::
|
|
256
258
|
https://doc-container4.streamlit.app/
|
|
257
259
|
height: 400px
|
|
258
260
|
|
|
@@ -268,7 +270,7 @@ class LayoutsMixin:
|
|
|
268
270
|
>>> for card in range(3):
|
|
269
271
|
>>> flex.button(f"Button {card + 1}")
|
|
270
272
|
|
|
271
|
-
.. output
|
|
273
|
+
.. output::
|
|
272
274
|
https://doc-container5.streamlit.app/
|
|
273
275
|
height: 250px
|
|
274
276
|
|
|
@@ -298,7 +300,7 @@ class LayoutsMixin:
|
|
|
298
300
|
block_proto.flex_container.justify = get_justify(vertical_alignment)
|
|
299
301
|
block_proto.flex_container.align = get_align(horizontal_alignment)
|
|
300
302
|
|
|
301
|
-
validate_width(width)
|
|
303
|
+
validate_width(width, allow_content=True)
|
|
302
304
|
block_proto.width_config.CopyFrom(get_width_config(width))
|
|
303
305
|
|
|
304
306
|
if isinstance(height, int) or border:
|
|
@@ -420,7 +422,7 @@ class LayoutsMixin:
|
|
|
420
422
|
... st.header("An owl")
|
|
421
423
|
... st.image("https://static.streamlit.io/examples/owl.jpg")
|
|
422
424
|
|
|
423
|
-
.. output
|
|
425
|
+
.. output::
|
|
424
426
|
https://doc-columns1.streamlit.app/
|
|
425
427
|
height: 620px
|
|
426
428
|
|
|
@@ -441,7 +443,7 @@ class LayoutsMixin:
|
|
|
441
443
|
>>> col2.subheader("A narrow column with the data")
|
|
442
444
|
>>> col2.write(df)
|
|
443
445
|
|
|
444
|
-
.. output
|
|
446
|
+
.. output::
|
|
445
447
|
https://doc-columns2.streamlit.app/
|
|
446
448
|
height: 550px
|
|
447
449
|
|
|
@@ -457,7 +459,7 @@ class LayoutsMixin:
|
|
|
457
459
|
>>> middle.button("Click me", use_container_width=True)
|
|
458
460
|
>>> right.checkbox("Check me")
|
|
459
461
|
|
|
460
|
-
.. output
|
|
462
|
+
.. output::
|
|
461
463
|
https://doc-columns-bottom-widgets.streamlit.app/
|
|
462
464
|
height: 200px
|
|
463
465
|
|
|
@@ -476,7 +478,7 @@ class LayoutsMixin:
|
|
|
476
478
|
>>> middle.image("https://static.streamlit.io/examples/dog.jpg")
|
|
477
479
|
>>> right.image("https://static.streamlit.io/examples/owl.jpg")
|
|
478
480
|
|
|
479
|
-
.. output
|
|
481
|
+
.. output::
|
|
480
482
|
https://doc-columns-vertical-alignment.streamlit.app/
|
|
481
483
|
height: 600px
|
|
482
484
|
|
|
@@ -493,7 +495,7 @@ class LayoutsMixin:
|
|
|
493
495
|
>>> middle.markdown("Lorem ipsum " * 5)
|
|
494
496
|
>>> right.markdown("Lorem ipsum ")
|
|
495
497
|
|
|
496
|
-
.. output
|
|
498
|
+
.. output::
|
|
497
499
|
https://doc-columns-borders.streamlit.app/
|
|
498
500
|
height: 250px
|
|
499
501
|
|
|
@@ -640,7 +642,7 @@ class LayoutsMixin:
|
|
|
640
642
|
... st.header("An owl")
|
|
641
643
|
... st.image("https://static.streamlit.io/examples/owl.jpg", width=200)
|
|
642
644
|
|
|
643
|
-
.. output
|
|
645
|
+
.. output::
|
|
644
646
|
https://doc-tabs1.streamlit.app/
|
|
645
647
|
height: 620px
|
|
646
648
|
|
|
@@ -661,7 +663,7 @@ class LayoutsMixin:
|
|
|
661
663
|
>>> tab2.subheader("A tab with the data")
|
|
662
664
|
>>> tab2.write(df)
|
|
663
665
|
|
|
664
|
-
.. output
|
|
666
|
+
.. output::
|
|
665
667
|
https://doc-tabs2.streamlit.app/
|
|
666
668
|
height: 700px
|
|
667
669
|
|
|
@@ -686,7 +688,7 @@ class LayoutsMixin:
|
|
|
686
688
|
>>> st.header("An owl")
|
|
687
689
|
>>> st.image("https://static.streamlit.io/examples/owl.jpg", width=200)
|
|
688
690
|
|
|
689
|
-
.. output
|
|
691
|
+
.. output::
|
|
690
692
|
https://doc-tabs3.streamlit.app/
|
|
691
693
|
height: 620px
|
|
692
694
|
|
|
@@ -791,6 +793,8 @@ class LayoutsMixin:
|
|
|
791
793
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
792
794
|
font library.
|
|
793
795
|
|
|
796
|
+
- ``"spinner"``: Displays a spinner as an icon.
|
|
797
|
+
|
|
794
798
|
width : "stretch" or int
|
|
795
799
|
The width of the expander container. This can be one of the following:
|
|
796
800
|
|
|
@@ -817,7 +821,7 @@ class LayoutsMixin:
|
|
|
817
821
|
... ''')
|
|
818
822
|
... st.image("https://static.streamlit.io/examples/dice.jpg")
|
|
819
823
|
|
|
820
|
-
.. output
|
|
824
|
+
.. output::
|
|
821
825
|
https://doc-expander.streamlit.app/
|
|
822
826
|
height: 750px
|
|
823
827
|
|
|
@@ -835,7 +839,7 @@ class LayoutsMixin:
|
|
|
835
839
|
... ''')
|
|
836
840
|
>>> expander.image("https://static.streamlit.io/examples/dice.jpg")
|
|
837
841
|
|
|
838
|
-
.. output
|
|
842
|
+
.. output::
|
|
839
843
|
https://doc-expander.streamlit.app/
|
|
840
844
|
height: 750px
|
|
841
845
|
|
|
@@ -941,6 +945,8 @@ class LayoutsMixin:
|
|
|
941
945
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
942
946
|
font library.
|
|
943
947
|
|
|
948
|
+
- ``"spinner"``: Displays a spinner as an icon.
|
|
949
|
+
|
|
944
950
|
disabled : bool
|
|
945
951
|
An optional boolean that disables the popover button if set to
|
|
946
952
|
``True``. The default is ``False``.
|
|
@@ -993,7 +999,7 @@ class LayoutsMixin:
|
|
|
993
999
|
>>>
|
|
994
1000
|
>>> st.write("Your name:", name)
|
|
995
1001
|
|
|
996
|
-
.. output
|
|
1002
|
+
.. output::
|
|
997
1003
|
https://doc-popover.streamlit.app/
|
|
998
1004
|
height: 400px
|
|
999
1005
|
|
|
@@ -1010,7 +1016,7 @@ class LayoutsMixin:
|
|
|
1010
1016
|
>>> if blue:
|
|
1011
1017
|
... st.write(":blue[This is a blue item.]")
|
|
1012
1018
|
|
|
1013
|
-
.. output
|
|
1019
|
+
.. output::
|
|
1014
1020
|
https://doc-popover2.streamlit.app/
|
|
1015
1021
|
height: 400px
|
|
1016
1022
|
|
|
@@ -1142,7 +1148,7 @@ class LayoutsMixin:
|
|
|
1142
1148
|
>>>
|
|
1143
1149
|
>>> st.button("Rerun")
|
|
1144
1150
|
|
|
1145
|
-
.. output
|
|
1151
|
+
.. output::
|
|
1146
1152
|
https://doc-status.streamlit.app/
|
|
1147
1153
|
height: 300px
|
|
1148
1154
|
|
|
@@ -1165,7 +1171,7 @@ class LayoutsMixin:
|
|
|
1165
1171
|
>>>
|
|
1166
1172
|
>>> st.button("Rerun")
|
|
1167
1173
|
|
|
1168
|
-
.. output
|
|
1174
|
+
.. output::
|
|
1169
1175
|
https://doc-status-update.streamlit.app/
|
|
1170
1176
|
height: 300px
|
|
1171
1177
|
|
|
@@ -46,6 +46,11 @@ if TYPE_CHECKING:
|
|
|
46
46
|
VegaLiteType: TypeAlias = Literal["quantitative", "ordinal", "temporal", "nominal"]
|
|
47
47
|
ChartStackType: TypeAlias = Literal["normalize", "center", "layered"]
|
|
48
48
|
|
|
49
|
+
# Threshold for applying hover event throttling on large datasets.
|
|
50
|
+
# For datasets with more points than this threshold, hover events are throttled
|
|
51
|
+
# to 16ms (~60fps) to improve performance.
|
|
52
|
+
_LARGE_DATASET_POINT_THRESHOLD: Final = 1000
|
|
53
|
+
|
|
49
54
|
|
|
50
55
|
class PrepDataColumns(TypedDict):
|
|
51
56
|
"""Columns used for the prep_data step in Altair Arrow charts."""
|
|
@@ -286,37 +291,65 @@ def generate_chart(
|
|
|
286
291
|
and is_altair_version_5_or_greater
|
|
287
292
|
):
|
|
288
293
|
return _add_improved_hover_tooltips(
|
|
289
|
-
chart, x_column, chart_width, chart_height
|
|
294
|
+
chart, x_column, chart_width, chart_height, len(df)
|
|
290
295
|
).interactive(), add_rows_metadata
|
|
291
296
|
|
|
292
297
|
return chart.interactive(), add_rows_metadata
|
|
293
298
|
|
|
294
299
|
|
|
295
300
|
def _add_improved_hover_tooltips(
|
|
296
|
-
chart: alt.Chart,
|
|
301
|
+
chart: alt.Chart,
|
|
302
|
+
x_column: str,
|
|
303
|
+
width: int | None,
|
|
304
|
+
height: int | None,
|
|
305
|
+
data_point_count: int,
|
|
297
306
|
) -> alt.LayerChart:
|
|
298
|
-
"""Adds improved hover tooltips to an existing line chart.
|
|
307
|
+
"""Adds improved hover tooltips to an existing line chart.
|
|
308
|
+
|
|
309
|
+
This implementation uses a three-layer approach for better performance:
|
|
310
|
+
1. Base chart layer: The original line chart
|
|
311
|
+
2. Detection layer: Invisible points for detecting the nearest point on hover
|
|
312
|
+
3. Highlight layer: Only renders the selected point(s) using transform_filter
|
|
313
|
+
|
|
314
|
+
The filter-based approach is more efficient than using conditional opacity
|
|
315
|
+
because it only renders the selected point(s) rather than evaluating opacity
|
|
316
|
+
for every single data point on each hover event.
|
|
317
|
+
"""
|
|
299
318
|
|
|
300
319
|
import altair as alt
|
|
301
320
|
|
|
302
|
-
#
|
|
321
|
+
# Throttle hover events for large datasets to 16ms (~60fps) to improve performance.
|
|
322
|
+
# For smaller datasets, use standard mousemove without throttling.
|
|
323
|
+
hover_event = (
|
|
324
|
+
"mousemove{16}"
|
|
325
|
+
if data_point_count > _LARGE_DATASET_POINT_THRESHOLD
|
|
326
|
+
else "mousemove"
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# Create a selection that chooses the nearest point & selects based on x-value.
|
|
330
|
+
# Uses mouseleave instead of mouseout/pointerout for more reliable hover clearing
|
|
331
|
+
# (mouseout fires when moving over child elements like tooltips).
|
|
303
332
|
nearest = alt.selection_point(
|
|
304
333
|
nearest=True,
|
|
305
|
-
on=
|
|
334
|
+
on=hover_event,
|
|
306
335
|
fields=[x_column],
|
|
307
336
|
empty=False,
|
|
308
|
-
clear="
|
|
337
|
+
clear="mouseleave",
|
|
309
338
|
)
|
|
310
339
|
|
|
311
|
-
#
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
340
|
+
# Detection layer: Invisible points for detecting the nearest point.
|
|
341
|
+
# This layer is needed because selections must be attached to a mark.
|
|
342
|
+
detection_points = chart.mark_point(opacity=0).add_params(nearest)
|
|
343
|
+
|
|
344
|
+
# Highlight layer: Only renders the selected point(s) using transform_filter.
|
|
345
|
+
# This is more efficient than conditional opacity because it only renders
|
|
346
|
+
# the filtered data (typically 1-2 points) rather than all points.
|
|
347
|
+
highlighted_points = chart.mark_point(filled=True, size=65).transform_filter(
|
|
348
|
+
nearest
|
|
316
349
|
)
|
|
317
350
|
|
|
318
351
|
layer_chart = (
|
|
319
|
-
alt.layer(chart,
|
|
352
|
+
alt.layer(chart, detection_points, highlighted_points)
|
|
320
353
|
.configure_legend(symbolType="stroke")
|
|
321
354
|
.properties(
|
|
322
355
|
width=width or 0,
|
|
@@ -338,7 +371,7 @@ def prep_chart_data_for_add_rows(
|
|
|
338
371
|
"""
|
|
339
372
|
import pandas as pd
|
|
340
373
|
|
|
341
|
-
df =
|
|
374
|
+
df = dataframe_util.convert_anything_to_pandas_df(data)
|
|
342
375
|
|
|
343
376
|
# Make range indices start at last_index.
|
|
344
377
|
if isinstance(df.index, pd.RangeIndex):
|
|
@@ -431,7 +464,7 @@ def _infer_vegalite_type(
|
|
|
431
464
|
|
|
432
465
|
|
|
433
466
|
def _get_pandas_index_attr(
|
|
434
|
-
data: pd.DataFrame | pd.Series,
|
|
467
|
+
data: pd.DataFrame | pd.Series[Any],
|
|
435
468
|
attr: str,
|
|
436
469
|
) -> Any | None:
|
|
437
470
|
return getattr(data.index, attr, None)
|
|
@@ -634,7 +667,7 @@ def _drop_unused_columns(df: pd.DataFrame, *column_names: str | None) -> pd.Data
|
|
|
634
667
|
seen.add(x)
|
|
635
668
|
keep.append(x)
|
|
636
669
|
|
|
637
|
-
return df[keep]
|
|
670
|
+
return df[keep] # ty: ignore[invalid-return-type]
|
|
638
671
|
|
|
639
672
|
|
|
640
673
|
def _maybe_convert_color_column_in_place(
|
|
@@ -651,7 +684,7 @@ def _maybe_convert_color_column_in_place(
|
|
|
651
684
|
pass
|
|
652
685
|
elif is_color_tuple_like(first_color_datum):
|
|
653
686
|
# Tuples need to be converted to CSS-valid.
|
|
654
|
-
df.loc[:, color_column] = df[color_column].
|
|
687
|
+
df.loc[:, color_column] = df[color_column].apply(to_css_color)
|
|
655
688
|
else:
|
|
656
689
|
# Other kinds of colors columns (i.e. pure numbers or nominal strings) shouldn't
|
|
657
690
|
# be converted since they are treated by Vega-Lite as sequential or categorical
|
|
@@ -219,7 +219,7 @@ def _normalize_tuple(
|
|
|
219
219
|
r = rgb_formatter(color_4tuple[0], color_4tuple)
|
|
220
220
|
g = rgb_formatter(color_4tuple[1], color_4tuple)
|
|
221
221
|
b = rgb_formatter(color_4tuple[2], color_4tuple)
|
|
222
|
-
alpha = alpha_formatter(color_4tuple[3], color_4tuple)
|
|
222
|
+
alpha = alpha_formatter(color_4tuple[3], color_4tuple) # ty: ignore[index-out-of-bounds]
|
|
223
223
|
return r, g, b, alpha
|
|
224
224
|
|
|
225
225
|
raise StreamlitInvalidColorError(color)
|
|
@@ -18,7 +18,7 @@ import copy
|
|
|
18
18
|
import json
|
|
19
19
|
from collections.abc import Mapping
|
|
20
20
|
from enum import Enum
|
|
21
|
-
from typing import TYPE_CHECKING, Final, Literal, TypeAlias
|
|
21
|
+
from typing import TYPE_CHECKING, Any, Final, Literal, TypeAlias
|
|
22
22
|
|
|
23
23
|
from streamlit.dataframe_util import DataFormat
|
|
24
24
|
from streamlit.elements.lib.column_types import ColumnConfig, ColumnType
|
|
@@ -208,7 +208,7 @@ def _determine_data_kind_via_arrow(field: pa.Field) -> ColumnDataKind:
|
|
|
208
208
|
|
|
209
209
|
|
|
210
210
|
def _determine_data_kind_via_pandas_dtype(
|
|
211
|
-
column: Series | Index,
|
|
211
|
+
column: Series[Any] | Index[Any],
|
|
212
212
|
) -> ColumnDataKind:
|
|
213
213
|
"""Determine the data kind by using the pandas dtype.
|
|
214
214
|
|
|
@@ -262,7 +262,7 @@ def _determine_data_kind_via_pandas_dtype(
|
|
|
262
262
|
|
|
263
263
|
|
|
264
264
|
def _determine_data_kind_via_inferred_type(
|
|
265
|
-
column: Series | Index,
|
|
265
|
+
column: Series[Any] | Index[Any],
|
|
266
266
|
) -> ColumnDataKind:
|
|
267
267
|
"""Determine the data kind by inferring it from the underlying data.
|
|
268
268
|
|
|
@@ -331,7 +331,7 @@ def _determine_data_kind_via_inferred_type(
|
|
|
331
331
|
|
|
332
332
|
|
|
333
333
|
def _determine_data_kind(
|
|
334
|
-
column: Series | Index, field: pa.Field | None = None
|
|
334
|
+
column: Series[Any] | Index[Any], field: pa.Field | None = None
|
|
335
335
|
) -> ColumnDataKind:
|
|
336
336
|
"""Determine the data kind of a column.
|
|
337
337
|
|
|
@@ -395,7 +395,8 @@ def determine_dataframe_schema(
|
|
|
395
395
|
|
|
396
396
|
# Add types for all columns:
|
|
397
397
|
for i, column in enumerate(data_df.items()):
|
|
398
|
-
column_name
|
|
398
|
+
column_name = str(column[0])
|
|
399
|
+
column_data = column[1]
|
|
399
400
|
dataframe_schema[column_name] = _determine_data_kind(
|
|
400
401
|
column_data, arrow_schema.field(i)
|
|
401
402
|
)
|
|
@@ -21,12 +21,14 @@ from streamlit.errors import (
|
|
|
21
21
|
StreamlitInvalidHeightError,
|
|
22
22
|
StreamlitInvalidHorizontalAlignmentError,
|
|
23
23
|
StreamlitInvalidSizeError,
|
|
24
|
+
StreamlitInvalidTextAlignmentError,
|
|
24
25
|
StreamlitInvalidVerticalAlignmentError,
|
|
25
26
|
StreamlitInvalidWidthError,
|
|
26
27
|
)
|
|
27
28
|
from streamlit.proto.Block_pb2 import Block
|
|
28
29
|
from streamlit.proto.GapSize_pb2 import GapSize
|
|
29
30
|
from streamlit.proto.HeightConfig_pb2 import HeightConfig
|
|
31
|
+
from streamlit.proto.TextAlignmentConfig_pb2 import TextAlignmentConfig
|
|
30
32
|
from streamlit.proto.WidthConfig_pb2 import WidthConfig
|
|
31
33
|
|
|
32
34
|
WidthWithoutContent: TypeAlias = int | Literal["stretch"]
|
|
@@ -37,6 +39,7 @@ SpaceSize: TypeAlias = int | Literal["stretch", "small", "medium", "large"]
|
|
|
37
39
|
Gap: TypeAlias = Literal["small", "medium", "large"]
|
|
38
40
|
HorizontalAlignment: TypeAlias = Literal["left", "center", "right", "distribute"]
|
|
39
41
|
VerticalAlignment: TypeAlias = Literal["top", "center", "bottom", "distribute"]
|
|
42
|
+
TextAlignment: TypeAlias = Literal["left", "center", "right", "justify"]
|
|
40
43
|
|
|
41
44
|
# Mapping of size literals to rem values for st.space
|
|
42
45
|
# If changing these, also check streamlit/frontend/lib/src/theme/primitives/sizes.ts
|
|
@@ -52,6 +55,7 @@ SIZE_TO_REM_MAPPING = {
|
|
|
52
55
|
class LayoutConfig:
|
|
53
56
|
width: Width | SpaceSize | None = None
|
|
54
57
|
height: Height | SpaceSize | None = None
|
|
58
|
+
text_alignment: TextAlignment | None = None
|
|
55
59
|
|
|
56
60
|
|
|
57
61
|
def validate_width(width: Width, allow_content: bool = False) -> None:
|
|
@@ -210,6 +214,24 @@ def validate_vertical_alignment(vertical_alignment: VerticalAlignment) -> None:
|
|
|
210
214
|
raise StreamlitInvalidVerticalAlignmentError(vertical_alignment, "st.container")
|
|
211
215
|
|
|
212
216
|
|
|
217
|
+
def validate_text_alignment(text_alignment: TextAlignment) -> None:
|
|
218
|
+
"""Validate the text_alignment parameter.
|
|
219
|
+
|
|
220
|
+
Parameters
|
|
221
|
+
----------
|
|
222
|
+
text_alignment : TextAlignment
|
|
223
|
+
The text alignment value to validate.
|
|
224
|
+
|
|
225
|
+
Raises
|
|
226
|
+
------
|
|
227
|
+
StreamlitInvalidTextAlignmentError
|
|
228
|
+
If the text_alignment value is invalid.
|
|
229
|
+
"""
|
|
230
|
+
valid_alignments = ["left", "center", "right", "justify"]
|
|
231
|
+
if text_alignment not in valid_alignments:
|
|
232
|
+
raise StreamlitInvalidTextAlignmentError(text_alignment)
|
|
233
|
+
|
|
234
|
+
|
|
213
235
|
map_to_flex_terminology = {
|
|
214
236
|
"left": "start",
|
|
215
237
|
"center": "center",
|
|
@@ -249,3 +271,31 @@ def get_align(
|
|
|
249
271
|
"Block.FlexContainer.Align.ValueType",
|
|
250
272
|
getattr(Block.FlexContainer.Align, f"ALIGN_{align.upper()}"),
|
|
251
273
|
)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def get_text_alignment_config(
|
|
277
|
+
text_alignment: TextAlignment,
|
|
278
|
+
) -> TextAlignmentConfig:
|
|
279
|
+
"""Convert text alignment string to proto config.
|
|
280
|
+
|
|
281
|
+
Parameters
|
|
282
|
+
----------
|
|
283
|
+
text_alignment : TextAlignment
|
|
284
|
+
The text alignment value ("left", "center", "right", "justify").
|
|
285
|
+
|
|
286
|
+
Returns
|
|
287
|
+
-------
|
|
288
|
+
TextAlignmentConfig
|
|
289
|
+
Proto message with alignment set.
|
|
290
|
+
"""
|
|
291
|
+
|
|
292
|
+
alignment_mapping = {
|
|
293
|
+
"left": TextAlignmentConfig.Alignment.LEFT,
|
|
294
|
+
"center": TextAlignmentConfig.Alignment.CENTER,
|
|
295
|
+
"right": TextAlignmentConfig.Alignment.RIGHT,
|
|
296
|
+
"justify": TextAlignmentConfig.Alignment.JUSTIFY,
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
config = TextAlignmentConfig()
|
|
300
|
+
config.alignment = alignment_mapping[text_alignment]
|
|
301
|
+
return config
|