Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,15 @@ st.write(f'The selected button label is: {btn}')
[download_badge]: https://badgen.net/pypi/dm/streamlit-antd-components

[download_link]: https://pypi.org/project/streamlit-antd-components/#files

# Developer mode
In `frontend` folder run
```sh
npm install
npm run build
```

Then in source, you can debug the components in the [demo app](https://github.com/nicedouble/StreamlitAntdComponentsDemo). Via
```py
pip install .
```
7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ def readme() -> str:
Used for the long_description. It's nice, because now 1) we have a top
level README file and 2) it's easier to type in the README file than to put
a raw string in below.
:return: content of README.md

:param color: alert color,support 'success', 'info', 'warning', 'error' and mantine color, hex and rgb color
:param background_color: alert background color,support mantine color, hex and rgb color
:param size: alert size,support mantine size and int in px
:param font: alert font,support mantine font and str
:return: content of README.md
"""
return open(join(dirname(__file__), "readme.md")).read()

Expand Down
15 changes: 14 additions & 1 deletion streamlit_antd_components/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
"version": "0.2.0",
"private": true,
"dependencies": {
"@babel/core": "^7.23.7",
"@emotion/react": "^11.11.3",
"@mantine/core": "6.0.19",
"@mantine/hooks": "^6.0.19",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"antd": "^5.7.2",
"bootstrap-icons": "^1.10.5",
"npm-watch": "^0.11.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-fast-marquee": "^1.6.0",
Expand All @@ -21,7 +25,16 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"watch": "npm-watch"
},
"watch": {
"build": {
"patterns": [
"src"
],
"extensions": "js,tsx,css"
}
},
"eslintConfig": {
"extends": "react-app"
Expand Down
4 changes: 3 additions & 1 deletion streamlit_antd_components/frontend/src/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import AntdResult from "./ts/Result";
import {AntdTags} from "./ts/Tag";
import AntdPagination from "./ts/Pagination";
import AntdChip from "./ts/Chip";
import AntdColorPicker from "./ts/ColorPicker";

//named components
const componentsMap: any = {
Expand All @@ -34,7 +35,8 @@ const componentsMap: any = {
'result': AntdResult,
'tags': AntdTags,
'pagination': AntdPagination,
'chip': AntdChip
'chip': AntdChip,
'color_picker': AntdColorPicker,
}

export default componentsMap
7 changes: 7 additions & 0 deletions streamlit_antd_components/frontend/src/css/color_picker.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.ant-popover-content {
padding: 0 !important;
overflow: unset !important;
}
li.ant-colorpicker-menu-item {
overflow: unset !important;
}
37 changes: 37 additions & 0 deletions streamlit_antd_components/frontend/src/js/tags.react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";
import {deepCopy, getSize} from "./utils.react"
import {CustomIcon} from "../ts/utils";
import {AntdTags} from "../ts/Tag";

//recurve str property to react node
const strToNode = (obj, size) => {
return obj.map((item, idx) => {
let obj_copy = deepCopy(item)
obj_copy['key'] = idx
const icon = obj_copy['icon']
const tag = obj_copy['tag']
//add tag
if (tag) {
obj_copy.label = <div className={'d-flex align-items-center'}>
<div className={'mr-1'}>{obj_copy.label}</div>
<AntdTags
items={Array.isArray(tag) ? tag : [tag]}
align={'end'}
size={getSize(size) - 4}
style={{lineHeight: 1.2}}
/>
</div>
}
//add icon
if (icon) {
obj_copy.label = <div className={'d-flex align-items-center'}>
<CustomIcon icon={icon} style={{marginRight: obj_copy.label ? 5 : 0}}/>
<div className={'d-flex flex-grow-1'}>{obj_copy.label}
</div>
</div>
}
return obj_copy
})
}

export {strToNode}
22 changes: 21 additions & 1 deletion streamlit_antd_components/frontend/src/js/utils.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ const getSize = (size, base = MartineFontSize) => {
}


const getTheme = (props) => {
const color = props['color']
const font = props['font'] != null ? props['font'] : 'inherit'
const backgroundColor = props['background_color'] != null ? props['background_color'] : 'transparent'
const size = getSize(props['size'] != null ? props['size'] : 'md')
const primaryColor = GetColor(color == null ? '--primary-color' : color)
const textColor = GetColor('--text-color')
const theme = {
colorPrimary: color,
colorText: textColor,
fontSize: size,
fontFamily: font,
colorBgContainer: backgroundColor,
}
return {color, font, backgroundColor, size, primaryColor, textColor, theme}
}

const GetColor = (color) => {
const theme = useMantineTheme()
if (color.indexOf('--') === 0) {
Expand All @@ -53,6 +70,8 @@ const GetColor = (color) => {
}
}
}


const RgbaColor = (color, alpha = 0.2) => {
const theme = useMantineTheme()
return theme.fn.rgba(color, alpha)
Expand Down Expand Up @@ -249,5 +268,6 @@ export {
insertStyle,
MartineFontSize,
MartineRadiusSize,
GetColor, RgbaColor, DarkenColor,LightenColor, getSize, getFlexDirection
GetColor, RgbaColor, DarkenColor, LightenColor, getFlexDirection,
getTheme, getSize
};
14 changes: 6 additions & 8 deletions streamlit_antd_components/frontend/src/ts/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import {Streamlit} from "streamlit-component-lib";
import React, {useEffect} from "react";
import {Alert, ConfigProvider} from 'antd';
import {GetColor, getSize, insertStyle, MartineRadiusSize, RgbaColor, markdown} from "../js/utils.react";
import {GetColor, getSize, getTheme, insertStyle, markdown, MartineRadiusSize, RgbaColor} from "../js/utils.react";
import Marquee from "react-fast-marquee";
import {CustomIcon} from "./utils";
import {BaseProp, CustomIcon} from "./utils";

interface AlertProp {
interface AlertProp extends BaseProp {
label: string;
description: string;
size: any
color: any
radius: any
variant: any
icon: any
Expand All @@ -21,13 +19,13 @@ const AntdAlert = (props: AlertProp) => {
//get data
const message = props['label']
const description = props['description']
const size = props['size']
const color = props['color']
const radius = props['radius']
const variant = props['variant']
const icon = props['icon']
const closable = props['closable']
const banner = props['banner']
const {color, font, backgroundColor, size, primaryColor, textColor, theme} = getTheme(props);

const colorList: any = {
'info': {'primary': 'rgb(0, 66, 128)', 'lighten': 'rgba(28, 131, 225, 0.1)'},
'success': {'primary': 'rgb(23, 114, 51)', 'lighten': 'rgba(33, 195, 84, 0.1)'},
Expand Down Expand Up @@ -116,7 +114,7 @@ const AntdAlert = (props: AlertProp) => {
theme={{
components: {
Alert: {
fontSize: getSize(size),
...theme
},
},
}}
Expand Down
62 changes: 31 additions & 31 deletions streamlit_antd_components/frontend/src/ts/Buttons.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import {Streamlit} from "streamlit-component-lib";
import React, {useEffect, useRef, useState} from "react";
import {Button, Space, ConfigProvider} from 'antd';
import {getHrefKeys, insertStyle, GetColor, RgbaColor, MartineRadiusSize, getSize} from "../js/utils.react"
import {CustomIcon, LabelWrap} from "./utils";
import {Button, ConfigProvider, Space} from 'antd';
import {getHrefKeys, getSize, getTheme, insertStyle, MartineRadiusSize, RgbaColor} from "../js/utils.react"
import {BaseProp, CustomIcon, LabelWrap} from "./utils";
import "../css/buttons.css"

interface ButtonsProp {
interface ButtonsProp extends BaseProp {
label: any;
description: any;
items: any[];
index: number | null;
variant: string;
align: any;
size: any
radius: any
color: any
background_color: any;
direction: "horizontal" | "vertical" | undefined;
gap: any;
use_container_width: boolean;
Expand All @@ -23,40 +22,41 @@ interface ButtonsProp {
stValue: any
}

interface ButtonProp {
interface ButtonProp extends BaseProp {
label: any;
icon: any;
disabled: any;
href: any;
color: any;
}

const AntdButton = (idx: any, type_: any, size: any, color: any, radius: any, props: ButtonProp, onClick: any, isSelect: boolean, grow: boolean) => {
const textColor = GetColor('--text-color')
const primary_color = GetColor(props['color'] != null ? props['color'] : color != null ? color : '--primary-color')
const text_color = props['color'] != null ? props['color'] : textColor

const AntdButton = (idx: any, type_: any, radius: any, props: ButtonProp, onClick: any, isSelect: boolean, grow: boolean) => {
//get data
const {color, font, backgroundColor, size, primaryColor, textColor, theme} = getTheme(props);

const linkColor = props['color'] != null ? props['color'] : '#1677ff'

let selectStyle = `
#btn-${idx}.ant-btn-default:not(:disabled):active,#btn-${idx}.ant-btn-dashed:not(:disabled):active {
color: #fff !important;
border-color: ${primary_color} !important;
background: ${primary_color} !important;
border-color: ${primaryColor} !important;
background: ${primaryColor} !important;
}
#btn-${idx}.ant-btn-primary:not(:disabled):active {
color: ${primary_color} !important;
color: ${primaryColor} !important;
background: transparent !important;
border-color: ${primary_color} !important;
border-color: ${primaryColor} !important;
}
`
let unSelectStyle = `
#btn-${idx}.ant-btn-primary:not(:disabled):hover{
box-shadow: 0 0 3px ${primary_color}, 0 0 3px rgba(0, 0, 0, .05);
box-shadow: 0 0 3px ${primaryColor}, 0 0 3px rgba(0, 0, 0, .05);
}
#btn-${idx}.ant-btn-text:not(:disabled):hover{
color:${text_color};
color:${textColor};
}
#btn-${idx}.ant-btn-text{
color:${text_color};
color:${textColor};
}
#btn-${idx}.ant-btn-text:disabled{
color:${RgbaColor(textColor, 0.5)};
Expand All @@ -70,22 +70,19 @@ const AntdButton = (idx: any, type_: any, size: any, color: any, radius: any, pr
theme={{
components: {
Button: {
colorText: isSelect ? textColor : primary_color,
...theme,
colorText: isSelect ? textColor : primaryColor,
colorTextDisabled: RgbaColor(textColor, 0.5),
colorPrimary: primary_color,
colorBgContainerDisabled: 'transform',
colorBgContainer: 'transform',
colorPrimaryHover: primary_color,
colorPrimaryActive: primary_color,
colorPrimaryHover: primaryColor,
colorPrimaryActive: primaryColor,
colorBgTextHover: RgbaColor(textColor, 0.1),
colorLink: linkColor,
colorLinkHover: linkColor,
colorLinkActive: linkColor,
// controlHeight: 3 * getSize(size) - 10,
fontSize: getSize(size),
colorBorder: isSelect ? RgbaColor(textColor) : primary_color,
colorBorder: isSelect ? RgbaColor(textColor) : primaryColor,
borderRadius: getSize(radius, MartineRadiusSize),
fontFamily: 'var(--font)'
},
},
}}
Expand All @@ -108,22 +105,21 @@ const AntdButton = (idx: any, type_: any, size: any, color: any, radius: any, pr

const AntdButtons = (props: ButtonsProp) => {
//get data
const {color, font, backgroundColor, size, primaryColor, textColor, theme} = getTheme(props);

const label = props['label']
const description = props['description']
const items = props['items']
const index = props['index']
let variant = props['variant']
variant = variant === 'outline' ? 'default' : variant === 'filled' ? 'primary' : variant
const align = props['align']
const size = props['size']
const radius = props['radius']
const color = props['color']
const direction = props['direction']
const gap = props['gap']
const grow = props['use_container_width']
const return_index = props['return_index']
const kv = props['kv']
const textColor = GetColor('--text-color')

//load custom style
let style = `
Expand Down Expand Up @@ -188,7 +184,11 @@ const AntdButtons = (props: ButtonsProp) => {
const buttonGroup = items.map((item: any, idx) => {
let otherType = ['primary', 'default'].find((x) => x !== variant)
let type_: any = index != null ? selected === idx ? otherType : variant : variant
return AntdButton(idx, type_, size, color, radius, item, onClick, index != null, grow)
item.color = item.color != null ? item.color : color
item.background_color = item.background_color != null ? item.background_color : backgroundColor
item.size = item.size != null ? item.size : size
item.font = item.font != null ? item.font : font
return AntdButton(idx, type_, radius, item, onClick, index != null, grow)
}
)

Expand Down
Loading