/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
frontend/app/src/components/StreamlitDialog/SettingsDialog.tsx
223 строки
6 KB
Maya Barnes
Refactor `SettingsDialog` & add copyable version (#13791)
04 фев 2026, 01:32
Не верифицирован
04 фев 2026, 01:32
4ef65df
Код
Авторство
О чём код?
/** * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026) * * 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 { ChangeEvent, FC, memo, useCallback, useContext, useEffect, useRef, useState, } from "react" import { MetricsManager } from "@streamlit/app/src/MetricsManager" import { CopyButton, CUSTOM_THEME_NAME, Modal, ModalBody, ModalHeader, SessionInfo, StreamlitMarkdown, ThemeConfig, ThemeContext, UISelectbox, useEmotionTheme, } from "@streamlit/lib" import { StyledCheckbox, StyledDialogBody, StyledFullRow, StyledHeader, StyledLabel, StyledVersionRow, StyledVersionText, } from "./styled-components" import { UserSettings } from "./UserSettings" export interface Props { isServerConnected: boolean onClose: () => void onSave: (settings: UserSettings) => void settings: UserSettings allowRunOnSave: boolean animateModal: boolean metricsMgr: MetricsManager sessionInfo: SessionInfo } /** * Implements a dialog that is used to configure user settings. */ export const SettingsDialog: FC<Props> = memo(function SettingsDialog({ isServerConnected, onClose, onSave, settings, allowRunOnSave, animateModal, metricsMgr, sessionInfo, }) { const { activeTheme, availableThemes, setTheme } = useContext(ThemeContext) const theme = useEmotionTheme() const activeSettingsRef = useRef(settings) const isFirstRunRef = useRef(true) const [state, setState] = useState<UserSettings>({ ...settings }) const changeSingleSetting = useCallback( (name: string, value: boolean): void => { setState(prevState => ({ ...prevState, [name]: value })) }, [] ) useEffect(() => { if (isFirstRunRef.current) { isFirstRunRef.current = false return } activeSettingsRef.current = state onSave(activeSettingsRef.current) }, [onSave, state]) const handleCheckboxChange = useCallback( (e: ChangeEvent<HTMLInputElement>): void => { changeSingleSetting(e.target.name, e.target.checked) }, [changeSingleSetting] ) const handleThemeChange = useCallback( (themeName: string | null): void => { // The themeName from selector will always be Light, Dark, or Use System Setting // These are the names for default themes, and the display names for custom themes let newTheme = undefined if (themeName) { newTheme = availableThemes.find((theme: ThemeConfig) => theme.name.startsWith("Custom Theme") ? theme.displayName === themeName : theme.name === themeName ) } if (newTheme === undefined) { newTheme = availableThemes[0] } metricsMgr.enqueue("menuClick", { label: "changeTheme", }) setTheme(newTheme) }, [setTheme, metricsMgr, availableThemes] ) const getAvailableThemeChoices = useCallback(() => { return availableThemes.map(theme => { // Custom themes have a display name, default themes just use their name return theme.displayName ?? theme.name }) }, [availableThemes]) return ( <Modal animate={animateModal} isOpen onClose={onClose}> <ModalHeader>Settings</ModalHeader> <ModalBody> <StyledDialogBody> {allowRunOnSave && ( <StyledFullRow> <StyledHeader>Development</StyledHeader> <label> <StyledCheckbox disabled={!isServerConnected} type="checkbox" name="runOnSave" checked={state.runOnSave && isServerConnected} onChange={handleCheckboxChange} />{" "} Run on save </label> <StreamlitMarkdown source="Automatically updates the app when the underlying code is updated." allowHTML={false} isCaption /> </StyledFullRow> )} <StyledFullRow> <StyledHeader>Appearance</StyledHeader> <label> <StyledCheckbox type="checkbox" name="wideMode" checked={state.wideMode} onChange={handleCheckboxChange} />{" "} Wide mode </label> <StreamlitMarkdown source=" Turn on to make this app occupy the entire width of the screen." allowHTML={false} isCaption /> </StyledFullRow> {!!availableThemes.length && ( <StyledFullRow> <StyledLabel>Choose app theme</StyledLabel> <UISelectbox options={getAvailableThemeChoices()} disabled={activeTheme.name === CUSTOM_THEME_NAME} onChange={handleThemeChange} value={activeTheme.displayName ?? activeTheme.name} placeholder="" acceptNewOptions={false} /> </StyledFullRow> )} {/* Show our version string only if SessionInfo has been created. If Streamlit hasn't yet connected to the server, the SessionInfo singleton will be null. */} {sessionInfo.isSet && ( <StyledFullRow data-testid="stVersionInfo"> <StyledVersionRow data-testid="stVersionRow"> <StyledVersionText data-testid="stVersionText"> Made with Streamlit {sessionInfo.current.streamlitVersion} </StyledVersionText> <CopyButton text={sessionInfo.current.streamlitVersion} buttonSize={theme.iconSizes.lg} iconSize={theme.iconSizes.md} className="stVersionCopyButton" data-testid="stVersionCopyButton" copyLabel="Copy version to clipboard" copiedLabel="Copied" /> </StyledVersionRow> </StyledFullRow> )} </StyledDialogBody> </ModalBody> </Modal> ) })