打字稿新手,现在已经使用它 2 天了,主要是为我的 Streamlit 应用程序构建自定义组件。我创建了下面的导航栏,自定义组件是一个可以在侧边栏上单击的选项卡,尽管它的行为很奇怪。当我单击组件选项卡时,有时会加载相应的页面,有时则不会,如下所示:
我有预感,这可能是我编写打字稿代码的方式,也许是
onClick
函数。有没有更好的方法来做到这一点:
Streamlit.setComponentValue()
打字稿组件
import {
Streamlit,
StreamlitComponentBase,
withStreamlitConnection,
} from "streamlit-component-lib"
import React, { ReactNode } from "react"
interface State {
navLabel: string|number
}
class MyComponent extends StreamlitComponentBase<State> {
public state = {navLabel: ""}
public render = (): ReactNode => {
const labelName = this.props.args["name"]
const iconName = this.props.args["iconName"]
const { theme } = this.props
const styles: React.CSSProperties = {}
return (
<div className="navtab" onClick={this.onClicked}>
<div className="content">
<input type="radio" name="indicator" id="input-data"/>
<div className="list">
<label htmlFor="input-data" className="input-data">
<span><i className="material-icons">{iconName}</i></span>
<span className="text-display">{labelName}</span>
</label>
</div>
</div>
</div>
)
}
private onClicked = (): void => {
this.setState(
prevState => ({navLabel: this.props.args["name"]}),
() => Streamlit.setComponentValue(this.state.navLabel)
)
}
Python执行代码
import streamlit as st
import streamlit.components.v1 as components
def my_component(name, iconName, tabIndex, key=None):
component_value = _component_func(name=name, iconName=iconName, tabIndex=tabIndex, key=key, default='Option')
# We could modify the value returned from the component if we wanted.
# There's no need to do this in our simple example - but it's an option.
return component_value
with st.sidebar:
test = my_component(name='Dashboard', iconName='dashboard', tabIndex=1, key="1")
test_2 = my_component(name='Data Analysis', iconName='insights', tabIndex=2, key="2")
test_3 = my_component(name='Testing', iconName='business', tabIndex=3, key="3")
if test == 'Dashboard':
st.title("Dashboard")
st.write('Name of option is {}'.format(test))
elif test_2 == 'Data Analysis':
st.title("Data Analysis")
st.write('Name of option is {}'.format(test_2))
elif test_3 == "Testing":
st.title("Third one")
我能够使用 li 和 ul 元素来解决这个问题:
import {
Streamlit,
StreamlitComponentBase,
withStreamlitConnection,
} from "streamlit-component-lib"
import React, { ReactNode } from "react"
interface State {
label: string,
icon: string
}
class MyComponent extends StreamlitComponentBase<State> {
public render = (): ReactNode => {
const labelName:string[] = this.props.args["name"]
const iconName:string[] = this.props.args["iconName"]
let data:any[] = [];
iconName.forEach((v,i) =>
data= [...data, {"id":i+1, "label": labelName[i], "icon":v}]
)
this.state = {
icon:data[0].icon,
label:data[0].label
}
const res = data.map(({id, icon, label}) => (
<span>
<li className="tab"
key={id}
onClick={() => this.setState(
prevState => ({icon:icon, label:label}),
() => Streamlit.setComponentValue(label)
)}><i className="material-icons">{icon}</i><span className="labelName">{label}</span></li></span>
))
return (
<div className="navtab">
<ul className="tab-options">
{res}
</ul>
</div>
)
}
}