An e-commerce product card component for Streamlit
Project description
Streamlit Product Card
An e-commerce style product card component for Streamlit applications.
Easily display products with images, descriptions, prices, and an optional call-to-action button — all with customizable styling and layout.
Note: This project is forked from gamcoh/st-card and has been adapted and extended.
✨ Features
- Product Information: Product name, multi-line description, and price.
- Image Display: Position image at the top, bottom, left, or right.
- Call-to-Action: Optional button with customizable text.
- Click Handling:
- Make the entire card clickable.
- Make only the button clickable.
- Returns
Truewhen the designated element is clicked.
- Customization:
- Image padding.
- Enable/disable animations.
- CSS-in-JS style overrides for different card sections.
- Theme Aware: Integrates with Streamlit theming.
📦 Installation
pip install streamlit-product-card
🚀 Basic Usage
import streamlit as st
from streamlit_product_card import product_card
st.set_page_config(layout="centered")
st.title("My Awesome Product")
clicked = product_card(
product_name="Cool Gadget X",
description=["High-quality materials", "Latest technology", "Eco-friendly"],
price="$99.99",
product_image="[https://placehold.co/300x200/007bff/white?text=Gadget+X](https://placehold.co/300x200/007bff/white?text=Gadget+X)",
button_text="Buy Now",
use_button=True,
picture_position="top",
enable_animation=True
)
if clicked:
st.success("You clicked 'Buy Now' for Cool Gadget X!")
Entire Card Clickable Example:
clicked_card = product_card(
product_name="Another Item",
description="A brief description of this other item.",
product_image="[https://placehold.co/300x200/28a745/white?text=Another+Item](https://placehold.co/300x200/28a745/white?text=Another+Item)",
use_button=False, # Entire card is clickable
key="another_item_card" # Important for multiple components
)
if clicked_card:
st.info("You clicked the 'Another Item' card!")
🔧 Parameters
The product_card function accepts the following parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
product_name |
str |
Required | Title of the product. |
description |
str or List[str] |
None |
Single string or list for multi-line descriptions. |
price |
str or float |
None |
Product price (will be converted to string). |
product_image |
str |
None |
URL of the product image. |
button_text |
str |
"Add to Cart" |
Text on the CTA button. |
use_button |
bool |
False |
If True, only the button is clickable. Otherwise, the whole card is. |
picture_position |
str |
"top" |
Image position: "top", "bottom", "left", "right". |
picture_paddings |
bool |
False |
If True, adds inner padding to the image, matching card radius. |
enable_animation |
bool |
True |
Enables card hover/active scaling animation. |
on_button_click |
Optional[Callable[[], Any]] |
None |
Optional callback function invoked when the card/button is clicked. |
styles |
Optional[Dict[str, Dict[str, Any]]] |
None |
Custom CSS-in-JS styles for card sections (see "Custom Styling" below). |
key |
Optional[str] |
None |
Unique Streamlit key, essential if you have multiple product_card components. |
Returns:
(bool):Trueif the card (or button, ifuse_button=True) was clicked in the last interaction,Falseotherwise.
🎨 Custom Styling
Customize the look using the styles parameter. It accepts a dictionary where keys are "slots" (parts of the card) and values are dictionaries of CSS properties (use camelCase for CSS properties, e.g., backgroundColor).
Available slots for styling:
card: The main card container.title: The product name.text: The description area.price: The price tag.button: The button.image: The product image.
Example:
custom_styles = {
"card": {
"backgroundColor": "#f0f2f6",
"borderRadius": "15px",
"boxShadow": "0 4px 8px rgba(0,0,0,0.1)"
},
"title": {
"color": "#1a73e8",
"fontSize": "1.5rem",
"fontWeight": "bold"
},
"text": {
"fontStyle": "italic"
},
"price": {
"color": "green",
"fontSize": "1.8rem"
},
"button": {
"backgroundColor": "#ff4b4b",
"color": "white",
"borderRadius": "20px",
"padding": "12px 24px"
},
"image": {
"objectFit": "contain", # Options: 'cover', 'contain', 'fill', 'scale-down'
"border": "2px solid #ddd"
}
}
product_card(
product_name="Custom Style Product",
description="This card demonstrates custom styling.",
price="$49.99",
product_image="[https://placehold.co/300x200/ffc107/black?text=Styled](https://placehold.co/300x200/ffc107/black?text=Styled)",
styles=custom_styles,
key="custom_card"
)
🧪 Advanced Example
This example demonstrates iterating through different image positions and animation states.
import streamlit as st
from streamlit_product_card import product_card
st.set_page_config(layout="wide")
st.title("Product Card - Positions & Animations Demo")
st.markdown("---")
positions = ["top", "bottom", "left", "right"]
for animate in (True, False):
st.subheader(f"Animation {'On' if animate else 'Off'}")
cols = st.columns(len(positions)) # Create columns for horizontal layout
for i, pos in enumerate(positions):
with cols[i]:
st.markdown(f"**Pos: {pos}, Pad: False**")
if product_card(
product_name=f"Anim={animate}, Pos={pos}",
description="Demo description",
price="¥1,000",
product_image=(
f"[https://placehold.co/300x200/888888/000000](https://placehold.co/300x200/888888/000000)?"
f"text={pos.upper()}"
),
use_button=False,
picture_position=pos,
picture_paddings=False,
enable_animation=animate,
key=f"card_{animate}_{pos}_no_pad" # Unique key is important
):
st.success(
f"{pos} clicked (no padding, anim={animate})"
)
st.markdown(f"<br>**Pos: {pos}, Pad: True**", unsafe_allow_html=True) # Add some space
if product_card(
product_name=f"Anim={animate}, Pos={pos}",
description="Demo description",
price="¥1,000",
product_image=(
f"[https://placehold.co/300x200/AAAAAA/000000](https://placehold.co/300x200/AAAAAA/000000)?"
f"text={pos.upper()}"
),
use_button=False,
picture_position=pos,
picture_paddings=True,
enable_animation=animate,
key=f"card_{animate}_{pos}_pad" # Unique key
):
st.success(
f"{pos} clicked (padding, anim={animate})"
)
st.markdown("---") # Separator after each animation group
🛠️ Development
This component is built with React for the frontend.
To modify the frontend:
- Navigate to the frontend directory:
cd your_package_name/frontend
(Remember to replaceyour_package_namewith your actual package directory name, e.g.,streamlit_product_card) - Install dependencies:
npm install - Start the development server:
npm start
To build the frontend for production:
npm run build
Ensure you set _RELEASE = False in your_package_name/__init__.py for development and _RELEASE = True when packaging for distribution.
📄 License
This project is licensed under the MIT License. See the LICENSE file for details.
(Make sure you have a LICENSE file in the root of your project that this link can point to.)
🤝 Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue.
🙏 Acknowledgements
Originally forked from gamcoh/st-card. Many thanks for their foundational work.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file streamlit_product_card-0.1.3.tar.gz.
File metadata
- Download URL: streamlit_product_card-0.1.3.tar.gz
- Upload date:
- Size: 690.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0865cec685b590a33f07f6b9488ba4135068bcb81b425bec36cd8b7aade68402
|
|
| MD5 |
a75cb067d8a7682a9d50b19595a54e13
|
|
| BLAKE2b-256 |
e2880c33bc3e96560a16649cbe7c486326c7cb56fa10e852991eed0ab608a611
|
File details
Details for the file streamlit_product_card-0.1.3-py3-none-any.whl.
File metadata
- Download URL: streamlit_product_card-0.1.3-py3-none-any.whl
- Upload date:
- Size: 697.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b17bb62cd682b36c2dfebfeeacb3c629b487c294fdc9e0e5fdcc2eb9e4939bb
|
|
| MD5 |
52e05f3d8d290b8b9565f7d954567ee5
|
|
| BLAKE2b-256 |
0af94f3cf2275b83e94a6cbacfabded295bba096a7e4932a8ae2720325b8acaf
|