├── docs ├── examples │ └── vendor │ │ └── .gitkeep ├── templates │ ├── generated │ │ ├── .gitkeep │ │ └── docs │ │ │ └── .gitkeep │ ├── changelog.html │ ├── base.html │ ├── partials │ │ ├── scripts.html │ │ ├── v2-alert.html │ │ └── head.html │ ├── docs.html │ ├── macros │ │ ├── theme-explorer-navbar.html │ │ └── example-navbar.html │ └── example.html ├── Procfile ├── runtime.txt ├── components_page │ ├── components │ │ ├── __init__.py │ │ ├── card │ │ │ ├── layout │ │ │ │ └── __init__.py │ │ │ ├── sizing │ │ │ │ ├── __init__.py │ │ │ │ ├── css.py │ │ │ │ ├── grid.py │ │ │ │ └── utility.py │ │ │ ├── body.py │ │ │ ├── list_group.py │ │ │ ├── header_footer.py │ │ │ ├── ttl.py │ │ │ ├── simple.py │ │ │ ├── image.py │ │ │ ├── image_overlay.py │ │ │ ├── outline.py │ │ │ └── color.py │ │ ├── progress │ │ │ ├── progress.py │ │ │ ├── labels.py │ │ │ ├── stripes.py │ │ │ ├── height.py │ │ │ ├── multiple.py │ │ │ ├── background.py │ │ │ ├── animated.py │ │ │ └── interval.py │ │ ├── layout │ │ │ ├── grid_only.py │ │ │ ├── no_gutters.py │ │ │ ├── simple.py │ │ │ ├── width.py │ │ │ ├── simple_stack.py │ │ │ ├── horizontal_stack.py │ │ │ ├── breakpoints.py │ │ │ ├── horizontal.py │ │ │ ├── stack_spacers.py │ │ │ ├── order_offset.py │ │ │ └── vertical.py │ │ ├── pagination │ │ │ ├── simple.py │ │ │ ├── navigation.py │ │ │ ├── size.py │ │ │ ├── collapse.py │ │ │ └── callback.py │ │ ├── button_group │ │ │ ├── simple.py │ │ │ ├── mixed.py │ │ │ ├── outline.py │ │ │ ├── dropdown.py │ │ │ ├── vertical.py │ │ │ ├── size.py │ │ │ └── radios.py │ │ ├── toast │ │ │ ├── simple.py │ │ │ ├── auto_dismiss.py │ │ │ ├── icon_dismiss.py │ │ │ └── position.py │ │ ├── form │ │ │ ├── floating.py │ │ │ ├── inline.py │ │ │ ├── grid.py │ │ │ ├── feedback.py │ │ │ ├── simple.py │ │ │ └── dash_core.py │ │ ├── table │ │ │ ├── kwargs.py │ │ │ ├── helper.py │ │ │ ├── simple.py │ │ │ ├── helper_multi.py │ │ │ └── color.py │ │ ├── list_group │ │ │ ├── simple.py │ │ │ ├── active.py │ │ │ ├── flush.py │ │ │ ├── numbered.py │ │ │ ├── colors.py │ │ │ ├── horizontal.py │ │ │ ├── links.py │ │ │ └── content.py │ │ ├── badge │ │ │ ├── simple.py │ │ │ ├── positioned.py │ │ │ ├── size.py │ │ │ ├── color.py │ │ │ └── pills.py │ │ ├── placeholder │ │ │ ├── simple.py │ │ │ ├── animation.py │ │ │ ├── width.py │ │ │ ├── size.py │ │ │ ├── color.py │ │ │ └── loading.py │ │ ├── spinner │ │ │ ├── size.py │ │ │ ├── simple.py │ │ │ ├── button.py │ │ │ ├── grow.py │ │ │ └── loading.py │ │ ├── button │ │ │ ├── block.py │ │ │ ├── half_block.py │ │ │ ├── responsive_block.py │ │ │ ├── size.py │ │ │ ├── flex_block.py │ │ │ ├── active_disabled.py │ │ │ ├── download.py │ │ │ ├── usage.py │ │ │ ├── simple.py │ │ │ └── outline.py │ │ ├── dropdown │ │ │ ├── simple.py │ │ │ ├── dark.py │ │ │ ├── custom_style.py │ │ │ ├── size.py │ │ │ ├── content.py │ │ │ ├── alignment.py │ │ │ ├── style.py │ │ │ ├── direction.py │ │ │ └── menu_items.py │ │ ├── input │ │ │ ├── validation.py │ │ │ ├── number_input.py │ │ │ ├── text_label.py │ │ │ ├── select.py │ │ │ ├── size.py │ │ │ ├── simple.py │ │ │ ├── textarea.py │ │ │ ├── colorpicker.py │ │ │ ├── components_in_labels.py │ │ │ ├── selected_styles.py │ │ │ ├── radio_check_inline.py │ │ │ └── radio_check_standalone.py │ │ ├── nav │ │ │ ├── link_based.py │ │ │ ├── pill.py │ │ │ ├── vertical.py │ │ │ ├── fill.py │ │ │ ├── simple.py │ │ │ └── navlink.py │ │ ├── carousel │ │ │ ├── crossfade.py │ │ │ ├── controls.py │ │ │ ├── indicators.py │ │ │ ├── simple.py │ │ │ ├── captions.py │ │ │ ├── dark.py │ │ │ └── callback.py │ │ ├── input_group │ │ │ ├── check_radio.py │ │ │ ├── size.py │ │ │ └── button.py │ │ ├── breadcrumb │ │ │ └── simple.py │ │ ├── tabs │ │ │ ├── labels_with_icons.py │ │ │ ├── style.py │ │ │ ├── active_style.py │ │ │ ├── active_tab.py │ │ │ ├── card.py │ │ │ └── simple.py │ │ ├── popover │ │ │ ├── popover_components.py │ │ │ ├── simple.py │ │ │ ├── styling.py │ │ │ ├── popover_callback.py │ │ │ └── direction.py │ │ ├── alert │ │ │ ├── content.py │ │ │ ├── link.py │ │ │ ├── simple.py │ │ │ ├── auto_dismiss.py │ │ │ ├── icon.py │ │ │ └── dismiss.py │ │ ├── accordion │ │ │ ├── flush.py │ │ │ ├── collapsed.py │ │ │ ├── always_open.py │ │ │ ├── simple.py │ │ │ ├── callback.py │ │ │ └── always_open_callback.py │ │ ├── navbar │ │ │ └── simple.py │ │ ├── tooltip │ │ │ ├── placement.py │ │ │ ├── tooltip.py │ │ │ └── tooltip_callback.py │ │ ├── index │ │ │ └── simple.py │ │ ├── modal │ │ │ ├── fullscreen.py │ │ │ ├── simple.py │ │ │ ├── centered.py │ │ │ └── dismiss.py │ │ ├── fade.md │ │ ├── jumbotron.md │ │ ├── breadcrumb.md │ │ ├── collapse │ │ │ ├── simple.py │ │ │ └── horizontal.py │ │ ├── fade │ │ │ ├── fade.py │ │ │ └── transition.py │ │ ├── offcanvas │ │ │ ├── simple.py │ │ │ └── scrollable.py │ │ ├── jumbotron │ │ │ ├── simple.py │ │ │ └── custom.py │ │ ├── collapse.md │ │ ├── input_group.md │ │ ├── alert.md │ │ ├── tooltip.md │ │ └── table.md │ └── helpers.py ├── static │ ├── data_file.txt │ ├── images │ │ ├── favicon.ico │ │ ├── dbclogo128.png │ │ ├── examples │ │ │ ├── ss.png │ │ │ ├── git.png │ │ │ └── iris.png │ │ ├── placeholder286x180.png │ │ ├── portrait-placeholder.png │ │ ├── slide3.svg │ │ ├── slide1.svg │ │ └── slide2.svg │ ├── js │ │ ├── theme-switcher.js │ │ └── v2-alert.js │ └── loading.css ├── requirements.txt ├── demos │ └── theme_explorer │ │ ├── pagination.py │ │ ├── collapse.py │ │ ├── popover.py │ │ ├── toast.py │ │ ├── breadcrumb.py │ │ ├── card.py │ │ ├── offcanvas.py │ │ ├── tooltip.py │ │ ├── progress.py │ │ ├── modal.py │ │ ├── accordion.py │ │ ├── util.py │ │ ├── nav.py │ │ ├── fade.py │ │ ├── tabs.py │ │ ├── alert.py │ │ └── list_group.py └── run.py ├── src ├── setupTests.js ├── private │ ├── AccordionContext.js │ ├── DropdownMenuContext.js │ ├── types.js │ └── BootstrapColors.js └── components │ ├── form │ └── __tests__ │ │ ├── Form.test.js │ │ └── FormText.test.js │ ├── card │ └── __tests__ │ │ ├── CardBody.test.js │ │ ├── CardGroup.test.js │ │ ├── CardImg.test.js │ │ ├── CardFooter.test.js │ │ ├── CardHeader.test.js │ │ └── CardImgOverlay.test.js │ ├── nav │ └── __tests__ │ │ ├── NavItem.test.js │ │ └── NavbarToggler.test.js │ ├── modal │ └── __tests__ │ │ ├── ModalBody.test.js │ │ ├── ModalTitle.test.js │ │ ├── ModalFooter.test.js │ │ └── ModalHeader.test.js │ ├── popover │ └── __tests__ │ │ ├── PopoverBody.test.js │ │ └── PopoverHeader.test.js │ ├── input │ └── __tests__ │ │ ├── InputGroupText.test.js │ │ └── InputGroup.test.js │ └── layout │ └── __tests__ │ ├── Row.test.js │ ├── Container.test.js │ └── Stack.test.js ├── dash_bootstrap_components ├── _version.py └── icons.py ├── readme-images ├── layout.png └── logo.png ├── .babelrc ├── tests ├── test_version.py ├── test_alert.py └── test_tooltip.py ├── examples ├── gallery │ ├── wordcloud │ │ └── requirements.txt │ ├── faithful │ │ └── requirements.txt │ ├── telephones-by-region │ │ ├── requirements.txt │ │ └── data.csv │ ├── iris-kmeans │ │ └── requirements.txt │ └── README.md └── templates │ ├── README.md │ └── multi-page-apps │ ├── sidebar-with-submenus │ └── assets │ │ └── sidebar-with-submenus.css │ └── responsive-sidebar │ └── assets │ └── responsive-sidebar.css ├── webpack ├── directories.js ├── moduleDefinition.js ├── config.dist.js ├── config.demo.js └── config.lib.js ├── demo ├── index.js └── index.html ├── .prettierrc ├── NOTICE.txt ├── .github ├── ISSUE_TEMPLATE │ ├── feature.md │ ├── feature-request.md │ ├── bug.md │ └── bug-report.md └── workflows │ └── test-build.yml ├── .gitignore └── eslint.config.mjs /docs/examples/vendor/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/templates/generated/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn run 2 | -------------------------------------------------------------------------------- /docs/runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.9.13 2 | -------------------------------------------------------------------------------- /docs/templates/generated/docs/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components_page/components/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components_page/components/card/layout/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components_page/components/card/sizing/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | -------------------------------------------------------------------------------- /dash_bootstrap_components/_version.py: -------------------------------------------------------------------------------- 1 | __version__ = "2.0.5-dev" 2 | -------------------------------------------------------------------------------- /docs/static/data_file.txt: -------------------------------------------------------------------------------- 1 | This is an example data file used to demonstrate the download option in Buttons. -------------------------------------------------------------------------------- /readme-images/layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/readme-images/layout.png -------------------------------------------------------------------------------- /readme-images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/readme-images/logo.png -------------------------------------------------------------------------------- /docs/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/docs/static/images/favicon.ico -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"], 3 | "plugins": ["@babel/plugin-transform-runtime"] 4 | } 5 | -------------------------------------------------------------------------------- /docs/static/images/dbclogo128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/docs/static/images/dbclogo128.png -------------------------------------------------------------------------------- /docs/static/images/examples/ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/docs/static/images/examples/ss.png -------------------------------------------------------------------------------- /docs/components_page/components/progress/progress.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | progress = dbc.Progress(value=50) 4 | -------------------------------------------------------------------------------- /docs/static/images/examples/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/docs/static/images/examples/git.png -------------------------------------------------------------------------------- /docs/static/images/examples/iris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/docs/static/images/examples/iris.png -------------------------------------------------------------------------------- /docs/components_page/components/progress/labels.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | progress = dbc.Progress(label="25%", value=25) 4 | -------------------------------------------------------------------------------- /docs/components_page/components/progress/stripes.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | progress = dbc.Progress(value=75, striped=True) 4 | -------------------------------------------------------------------------------- /docs/static/images/placeholder286x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/docs/static/images/placeholder286x180.png -------------------------------------------------------------------------------- /tests/test_version.py: -------------------------------------------------------------------------------- 1 | from dash_bootstrap_components import __version__ 2 | 3 | 4 | def test_version(): 5 | assert __version__ == "2.0.5-dev" 6 | -------------------------------------------------------------------------------- /docs/static/images/portrait-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbc-team/dash-bootstrap-components/HEAD/docs/static/images/portrait-placeholder.png -------------------------------------------------------------------------------- /examples/gallery/wordcloud/requirements.txt: -------------------------------------------------------------------------------- 1 | dash>=2.0.0 2 | dash-bootstrap-components 3 | dash-core-components 4 | dash-html-components 5 | matplotlib 6 | wordcloud 7 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | dash>=3.0.0 2 | dash_bootstrap_components==2.0.4 3 | gunicorn 4 | markdown 5 | pandas 6 | pymdown-extensions 7 | scikit-learn 8 | werkzeug>=1.0.0 9 | -------------------------------------------------------------------------------- /examples/gallery/faithful/requirements.txt: -------------------------------------------------------------------------------- 1 | dash>=2.0.0 2 | dash-bootstrap-components 3 | dash-core-components 4 | dash-html-components 5 | pandas 6 | plotly 7 | scipy 8 | -------------------------------------------------------------------------------- /examples/gallery/telephones-by-region/requirements.txt: -------------------------------------------------------------------------------- 1 | dash>2.0.0 2 | dash-bootstrap-components 3 | dash-core-components 4 | dash-html-components 5 | pandas 6 | plotly 7 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/grid_only.py: -------------------------------------------------------------------------------- 1 | import dash 2 | import dash_bootstrap_components as dbc 3 | 4 | app = dash.Dash(external_stylesheets=[dbc.themes.GRID]) 5 | -------------------------------------------------------------------------------- /examples/gallery/iris-kmeans/requirements.txt: -------------------------------------------------------------------------------- 1 | dash>=2.0.0 2 | dash-bootstrap-components 3 | dash-core-components 4 | dash-html-components 5 | pandas 6 | plotly 7 | scikit-learn 8 | -------------------------------------------------------------------------------- /docs/components_page/components/pagination/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | pagination = html.Div( 5 | dbc.Pagination(max_value=10), 6 | ) 7 | -------------------------------------------------------------------------------- /examples/templates/README.md: -------------------------------------------------------------------------------- 1 | # App templates 2 | 3 | These examples have minimal content, but are intended to demonstrate how you 4 | could structure layouts in your apps using dash-bootstrap-components. 5 | -------------------------------------------------------------------------------- /docs/components_page/components/button_group/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | button_group = dbc.ButtonGroup( 4 | [dbc.Button("Left"), dbc.Button("Middle"), dbc.Button("Right")] 5 | ) 6 | -------------------------------------------------------------------------------- /dash_bootstrap_components/icons.py: -------------------------------------------------------------------------------- 1 | BOOTSTRAP = ( 2 | "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" 3 | ) 4 | FONT_AWESOME = "https://use.fontawesome.com/releases/v6.7.2/css/all.css" 5 | -------------------------------------------------------------------------------- /webpack/directories.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var path = require('path'); 4 | 5 | var ROOT = process.cwd(); 6 | 7 | module.exports = { 8 | ROOT: ROOT, 9 | SRC: path.join(ROOT, 'src'), 10 | DEMO: path.join(ROOT, 'demo'), 11 | }; 12 | -------------------------------------------------------------------------------- /demo/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {createRoot} from 'react-dom/client'; 4 | 5 | import Demo from './Demo'; 6 | 7 | const root = createRoot(document.getElementById('react-demo-entry-point')); 8 | 9 | root.render(); 10 | -------------------------------------------------------------------------------- /docs/components_page/components/toast/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | toast = dbc.Toast( 5 | [html.P("This is the content of the toast", className="mb-0")], 6 | header="This is the header", 7 | ) 8 | -------------------------------------------------------------------------------- /docs/components_page/components/form/floating.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | form = dbc.FormFloating( 4 | [ 5 | dbc.Input(type="email", placeholder="example@internet.com"), 6 | dbc.Label("Email address"), 7 | ] 8 | ) 9 | -------------------------------------------------------------------------------- /src/private/AccordionContext.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * AccordionContext 5 | * { 6 | * toggle: PropTypes.func.isRequired, 7 | * idx: PropTypes.number.isRequired 8 | * } 9 | */ 10 | export const AccordionContext = React.createContext({}); 11 | -------------------------------------------------------------------------------- /docs/components_page/components/table/kwargs.py: -------------------------------------------------------------------------------- 1 | table = dbc.Table( 2 | # using the same table as in the above example 3 | table_header + table_body, 4 | bordered=True, 5 | color="dark", 6 | hover=True, 7 | responsive=True, 8 | striped=True, 9 | ) 10 | -------------------------------------------------------------------------------- /src/private/DropdownMenuContext.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * DropdownContext 5 | * { 6 | * toggle: PropTypes.func.isRequired, 7 | * isOpen: PropTypes.bool.isRequired 8 | * } 9 | */ 10 | export const DropdownMenuContext = React.createContext({}); 11 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | list_group = dbc.ListGroup( 4 | [ 5 | dbc.ListGroupItem("Item 1"), 6 | dbc.ListGroupItem("Item 2"), 7 | dbc.ListGroupItem("Item 3"), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /docs/components_page/components/badge/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | badge = dbc.Button( 4 | [ 5 | "Notifications", 6 | dbc.Badge("4", color="light", text_color="primary", className="ms-1"), 7 | ], 8 | color="primary", 9 | ) 10 | -------------------------------------------------------------------------------- /docs/components_page/components/placeholder/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | placeholder = html.Div( 5 | [ 6 | dbc.Placeholder(xs=6), 7 | html.Br(), 8 | dbc.Placeholder(xs=4, button=True), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/active.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | list_group = dbc.ListGroup( 4 | [ 5 | dbc.ListGroupItem("Active item", active=True), 6 | dbc.ListGroupItem("Item 2"), 7 | dbc.ListGroupItem("Item 3"), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/flush.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | list_group = dbc.ListGroup( 4 | [ 5 | dbc.ListGroupItem("Item 1"), 6 | dbc.ListGroupItem("Item 2"), 7 | dbc.ListGroupItem("Item 3"), 8 | ], 9 | flush=True, 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/button_group/mixed.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | button_group = dbc.ButtonGroup( 4 | [ 5 | dbc.Button("Left", color="danger"), 6 | dbc.Button("Middle", color="warning"), 7 | dbc.Button("Right", color="success"), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/numbered.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | list_group = dbc.ListGroup( 4 | [ 5 | dbc.ListGroupItem("Item 1"), 6 | dbc.ListGroupItem("Item 2"), 7 | dbc.ListGroupItem("Item 3"), 8 | ], 9 | numbered=True, 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/spinner/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | spinners = html.Div( 5 | [ 6 | dbc.Spinner(size="sm"), 7 | html.Hr(), 8 | dbc.Spinner(spinner_style={"width": "3rem", "height": "3rem"}), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/placeholder/animation.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | placeholder = html.Div( 5 | [ 6 | dbc.Placeholder(animation="glow", className="w-100"), 7 | dbc.Placeholder(animation="wave", className="w-100"), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /docs/components_page/components/progress/height.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | progress = html.Div( 5 | [ 6 | dbc.Progress(value=50, style={"height": "1px"}, className="mb-3"), 7 | dbc.Progress(value=50, style={"height": "30px"}), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /docs/static/js/theme-switcher.js: -------------------------------------------------------------------------------- 1 | function handleChange(e) { 2 | if (e.target.value) { 3 | document 4 | .getElementById('explorer-iframe') 5 | .setAttribute('src', '/docs/themes/explorer/' + e.target.value); 6 | } 7 | } 8 | 9 | document.getElementById('theme-switcher').onchange = handleChange; 10 | -------------------------------------------------------------------------------- /docs/components_page/components/button/block.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | button = html.Div( 5 | [ 6 | dbc.Button("Block button", color="primary"), 7 | dbc.Button("Block button", color="secondary"), 8 | ], 9 | className="d-grid gap-2", 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | dropdown = dbc.DropdownMenu( 4 | label="Menu", 5 | children=[ 6 | dbc.DropdownMenuItem("Item 1"), 7 | dbc.DropdownMenuItem("Item 2"), 8 | dbc.DropdownMenuItem("Item 3"), 9 | ], 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/input/validation.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | inputs = html.Div( 5 | [ 6 | dbc.Input(placeholder="Valid input...", valid=True, className="mb-3"), 7 | dbc.Input(placeholder="Invalid input...", invalid=True), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "singleQuote": true, 4 | "bracketSpacing": false, 5 | "arrowParens": "avoid", 6 | "trailingComma": "none", 7 | "importOrder": ["^react$", "", "^@/.*$", "^[./]"], 8 | "importOrderSeparation": true, 9 | "plugins": ["@trivago/prettier-plugin-sort-imports"] 10 | } 11 | -------------------------------------------------------------------------------- /docs/components_page/components/button/half_block.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | button = html.Div( 5 | [ 6 | dbc.Button("Block button", color="primary"), 7 | dbc.Button("Block button", color="secondary"), 8 | ], 9 | className="d-grid gap-2 col-6 mx-auto", 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/input/number_input.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | number_input = html.Div( 5 | [ 6 | html.P("Type a number outside the range 0-10"), 7 | dbc.Input(type="number", min=0, max=10, step=1), 8 | ], 9 | id="styled-numeric-input", 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/input/text_label.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | text_input = html.Div( 5 | [ 6 | dbc.Label("Text"), 7 | dbc.Input(placeholder="Input goes here...", type="text"), 8 | dbc.FormText("Type something in the box above"), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/button/responsive_block.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | button = html.Div( 5 | [ 6 | dbc.Button("Block button", color="primary"), 7 | dbc.Button("Block button", color="secondary"), 8 | ], 9 | className="d-grid gap-2 d-md-block", 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/progress/multiple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | progress = dbc.Progress( 4 | [ 5 | dbc.Progress(value=20, color="success", bar=True), 6 | dbc.Progress(value=30, color="warning", bar=True), 7 | dbc.Progress(value=20, color="danger", bar=True), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /docs/templates/changelog.html: -------------------------------------------------------------------------------- 1 | {% from "macros/navbar.html" import navbar %} 2 | {% extends "base.html" %} 3 | {% block header %}{{ navbar("more") }}{% endblock %} 4 | {% block body %} 5 |
6 |
{% block content %}{% endblock %}
7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /docs/components_page/components/button/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | buttons = html.Div( 5 | [ 6 | dbc.Button("Large button", size="lg", className="me-1"), 7 | dbc.Button("Regular button", className="me-1"), 8 | dbc.Button("Small button", size="sm"), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/dark.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | dropdown = dbc.DropdownMenu( 4 | label="Menu", 5 | menu_variant="dark", 6 | children=[ 7 | dbc.DropdownMenuItem("Item 1"), 8 | dbc.DropdownMenuItem("Item 2"), 9 | dbc.DropdownMenuItem("Item 3"), 10 | ], 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/input/select.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | select = dbc.Select( 4 | id="select", 5 | options=[ 6 | {"label": "Option 1", "value": "1"}, 7 | {"label": "Option 2", "value": "2"}, 8 | {"label": "Disabled option", "value": "3", "disabled": True}, 9 | ], 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/button_group/outline.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | button_group = dbc.ButtonGroup( 4 | [ 5 | dbc.Button("Left", outline=True, color="primary"), 6 | dbc.Button("Middle", outline=True, color="primary"), 7 | dbc.Button("Right", outline=True, color="primary"), 8 | ] 9 | ) 10 | -------------------------------------------------------------------------------- /examples/templates/multi-page-apps/sidebar-with-submenus/assets/sidebar-with-submenus.css: -------------------------------------------------------------------------------- 1 | .fa-chevron-right { 2 | transition: transform 0.2s ease-in-out 0s; 3 | } 4 | 5 | /* rotate the chevron when the open class is applied */ 6 | li.open .fa-chevron-right { 7 | transform: rotate(90deg); 8 | } 9 | 10 | .nav li { 11 | font-size: 18px; 12 | } 13 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | dash-bootstrap-components 2 | Copyright 2018-2025 Faculty Science Limited 3 | Copyright 2025 the dash-bootstrap-components maintainers 4 | 5 | This product includes software originally developed at Faculty Science Limited (https://faculty.ai/). 6 | 7 | The dash-bootstrap-components logo was originally designed by Bureau Bureau (https://bureaubureau.uk/). 8 | -------------------------------------------------------------------------------- /docs/components_page/components/nav/link_based.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | nav = dbc.Nav( 4 | [ 5 | dbc.NavLink("Active", active=True, href="#"), 6 | dbc.NavLink("A link", href="#"), 7 | dbc.NavLink("Another link", href="#"), 8 | dbc.NavLink("Disabled", disabled=True, href="#"), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/no_gutters.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | row = dbc.Row( 5 | [ 6 | dbc.Col(html.Div("One of three columns")), 7 | dbc.Col(html.Div("One of three columns")), 8 | dbc.Col(html.Div("One of three columns")), 9 | ], 10 | className="g-0", 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/placeholder/width.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | placeholder = html.Div( 5 | [ 6 | dbc.Placeholder(xs=6), 7 | html.Br(), 8 | dbc.Placeholder(className="w-75"), 9 | html.Br(), 10 | dbc.Placeholder(style={"width": "25%"}), 11 | ] 12 | ) 13 | -------------------------------------------------------------------------------- /tests/test_alert.py: -------------------------------------------------------------------------------- 1 | from dash import Dash, html 2 | from dash_bootstrap_components import Alert 3 | 4 | 5 | def test_dbal001_alert_content(dash_duo): 6 | app = Dash() 7 | 8 | app.layout = html.Div([Alert("Test content", id="alert")]) 9 | 10 | dash_duo.start_server(app) 11 | 12 | assert dash_duo.wait_for_element("#alert").text == "Test content" 13 | -------------------------------------------------------------------------------- /docs/components_page/components/card/body.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | cards = html.Div( 5 | [ 6 | dbc.Card( 7 | dbc.CardBody("This is some text within a card body"), 8 | className="mb-3", 9 | ), 10 | dbc.Card("This is also within a body", body=True), 11 | ] 12 | ) 13 | -------------------------------------------------------------------------------- /docs/components_page/components/pagination/navigation.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | pagination = html.Div( 5 | [ 6 | dbc.Pagination(max_value=5, first_last=True), 7 | dbc.Pagination(max_value=5, previous_next=True), 8 | dbc.Pagination(max_value=5, first_last=True, previous_next=True), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/card/list_group.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | card = dbc.Card( 4 | dbc.ListGroup( 5 | [ 6 | dbc.ListGroupItem("Item 1"), 7 | dbc.ListGroupItem("Item 2"), 8 | dbc.ListGroupItem("Item 3"), 9 | ], 10 | flush=True, 11 | ), 12 | style={"width": "18rem"}, 13 | ) 14 | -------------------------------------------------------------------------------- /docs/components_page/components/carousel/crossfade.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | carousel = dbc.Carousel( 4 | items=[ 5 | {"key": "1", "src": "/static/images/slide1.svg"}, 6 | {"key": "2", "src": "/static/images/slide2.svg"}, 7 | {"key": "3", "src": "/static/images/slide3.svg"}, 8 | ], 9 | className="carousel-fade", 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/button/flex_block.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | button = html.Div( 5 | [ 6 | dbc.Button("Button 1", className="me-md-2"), 7 | dbc.Button("Button 2", className="me-md-2"), 8 | dbc.Button("Button 3"), 9 | ], 10 | className="d-grid gap-2 d-md-flex justify-content-md-end", 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/table/helper.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | import pandas as pd 3 | 4 | df = pd.DataFrame( 5 | { 6 | "First Name": ["Arthur", "Ford", "Zaphod", "Trillian"], 7 | "Last Name": ["Dent", "Prefect", "Beeblebrox", "Astra"], 8 | } 9 | ) 10 | 11 | table = dbc.Table.from_dataframe(df, striped=True, bordered=True, hover=True) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/button/active_disabled.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | buttons = html.Div( 5 | [ 6 | dbc.Button("Regular", color="primary", className="me-1"), 7 | dbc.Button("Active", color="primary", active=True, className="me-1"), 8 | dbc.Button("Disabled", color="primary", disabled=True), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /docs/components_page/components/button/download.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | button = html.Div( 5 | [ 6 | dbc.Button( 7 | "Download", 8 | href="/static/data_file.txt", 9 | download="my_data.txt", 10 | external_link=True, 11 | color="primary", 12 | ), 13 | ] 14 | ) 15 | -------------------------------------------------------------------------------- /docs/components_page/components/carousel/controls.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | carousel = dbc.Carousel( 4 | items=[ 5 | {"key": "1", "src": "/static/images/slide1.svg"}, 6 | {"key": "2", "src": "/static/images/slide2.svg"}, 7 | {"key": "3", "src": "/static/images/slide3.svg"}, 8 | ], 9 | controls=True, 10 | indicators=False, 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/carousel/indicators.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | carousel = dbc.Carousel( 4 | items=[ 5 | {"key": "1", "src": "/static/images/slide1.svg"}, 6 | {"key": "2", "src": "/static/images/slide2.svg"}, 7 | {"key": "3", "src": "/static/images/slide3.svg"}, 8 | ], 9 | controls=True, 10 | indicators=True, 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/input/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | inputs = html.Div( 5 | [ 6 | dbc.Input(placeholder="A large input...", size="lg", className="mb-3"), 7 | dbc.Input(placeholder="A medium input...", size="md", className="mb-3"), 8 | dbc.Input(placeholder="A small input...", size="sm"), 9 | ] 10 | ) 11 | -------------------------------------------------------------------------------- /examples/gallery/telephones-by-region/data.csv: -------------------------------------------------------------------------------- 1 | Year,N.Amer,Europe,Asia,S.Amer,Oceania,Africa,Mid.Amer 2 | 1951,45939,21574,2876,1815,1646,89,555 3 | 1956,60423,29990,4708,2568,2366,1411,733 4 | 1957,64721,32510,5230,2695,2526,1546,773 5 | 1958,68484,35218,6662,2845,2691,1663,836 6 | 1959,71799,37598,6856,3000,2868,1769,911 7 | 1960,76036,40341,8220,3145,3054,1905,1008 8 | 1961,79831,43173,9053,3338,3224,2005,1076 9 | -------------------------------------------------------------------------------- /docs/components_page/components/input_group/check_radio.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | input_groups = html.Div( 5 | [ 6 | dbc.InputGroup( 7 | [dbc.InputGroupText(dbc.RadioButton()), dbc.Input()], 8 | className="mb-3", 9 | ), 10 | dbc.InputGroup([dbc.InputGroupText(dbc.Checkbox()), dbc.Input()]), 11 | ] 12 | ) 13 | -------------------------------------------------------------------------------- /docs/components_page/components/carousel/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | carousel = dbc.Carousel( 4 | items=[ 5 | {"key": "1", "src": "/static/images/slide1.svg"}, 6 | {"key": "2", "src": "/static/images/slide2.svg"}, 7 | {"key": "3", "src": "/static/images/slide3.svg"}, 8 | ], 9 | controls=False, 10 | indicators=False, 11 | interval=2000, 12 | ) 13 | -------------------------------------------------------------------------------- /docs/components_page/components/pagination/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | pagination = html.Div( 5 | [ 6 | html.Div("Small"), 7 | dbc.Pagination(max_value=5, size="sm"), 8 | html.Div("Default"), 9 | dbc.Pagination(max_value=5), 10 | html.Div("Large"), 11 | dbc.Pagination(max_value=5, size="lg"), 12 | ] 13 | ) 14 | -------------------------------------------------------------------------------- /docs/static/images/slide3.svg: -------------------------------------------------------------------------------- 1 | Third slide -------------------------------------------------------------------------------- /docs/components_page/components/button_group/dropdown.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | button_group = dbc.ButtonGroup( 4 | [ 5 | dbc.Button("First"), 6 | dbc.Button("Second"), 7 | dbc.DropdownMenu( 8 | [dbc.DropdownMenuItem("Item 1"), dbc.DropdownMenuItem("Item 2")], 9 | label="Dropdown", 10 | group=True, 11 | ), 12 | ] 13 | ) 14 | -------------------------------------------------------------------------------- /docs/components_page/components/nav/pill.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | nav = dbc.Nav( 4 | [ 5 | dbc.NavItem(dbc.NavLink("Active", active=True, href="#")), 6 | dbc.NavItem(dbc.NavLink("A link", href="#")), 7 | dbc.NavItem(dbc.NavLink("Another link", href="#")), 8 | dbc.NavItem(dbc.NavLink("Disabled", disabled=True, href="#")), 9 | ], 10 | pills=True, 11 | ) 12 | -------------------------------------------------------------------------------- /docs/static/images/slide1.svg: -------------------------------------------------------------------------------- 1 | First slide -------------------------------------------------------------------------------- /docs/static/images/slide2.svg: -------------------------------------------------------------------------------- 1 | Second slide -------------------------------------------------------------------------------- /docs/components_page/components/nav/vertical.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | nav = dbc.Nav( 4 | [ 5 | dbc.NavItem(dbc.NavLink("Active", active=True, href="#")), 6 | dbc.NavItem(dbc.NavLink("A link", href="#")), 7 | dbc.NavItem(dbc.NavLink("Another link", href="#")), 8 | dbc.NavItem(dbc.NavLink("Disabled", disabled=True, href="#")), 9 | ], 10 | vertical="md", 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/breadcrumb/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | breadcrumb = dbc.Breadcrumb( 4 | items=[ 5 | {"label": "Docs", "href": "/docs", "external_link": True}, 6 | { 7 | "label": "Components", 8 | "href": "/docs/components", 9 | "external_link": True, 10 | }, 11 | {"label": "Breadcrumb", "active": True}, 12 | ], 13 | ) 14 | -------------------------------------------------------------------------------- /docs/components_page/components/placeholder/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | placeholder = html.Div( 5 | [ 6 | dbc.Placeholder(size="xs", className="me-1 mt-1 w-100"), 7 | dbc.Placeholder(size="sm", className="me-1 mt-1 w-100"), 8 | dbc.Placeholder(className="me-1 mt-1 w-100"), 9 | dbc.Placeholder(size="lg", className="me-1 mt-1 w-100"), 10 | ] 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/progress/background.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | progress = html.Div( 5 | [ 6 | dbc.Progress(value=25, color="success", className="mb-3"), 7 | dbc.Progress(value=50, color="warning", className="mb-3"), 8 | dbc.Progress(value=75, color="danger", className="mb-3"), 9 | dbc.Progress(value=100, color="info"), 10 | ] 11 | ) 12 | -------------------------------------------------------------------------------- /docs/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block head %}{% include "partials/head.html" %}{% endblock %} 5 | {% block title %}{% endblock %} 6 | 7 | 8 | {% block header %}{% endblock %} 9 | {% include "partials/v2-alert.html" %} 10 | {% block body %}{% endblock %} 11 | {% block scripts %}{% include "partials/scripts.html" %}{% endblock %} 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/components_page/components/button_group/vertical.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | button_group = dbc.ButtonGroup( 4 | [ 5 | dbc.Button("First"), 6 | dbc.Button("Second"), 7 | dbc.DropdownMenu( 8 | [dbc.DropdownMenuItem("Item 1"), dbc.DropdownMenuItem("Item 2")], 9 | label="Dropdown", 10 | group=True, 11 | ), 12 | ], 13 | vertical=True, 14 | ) 15 | -------------------------------------------------------------------------------- /docs/components_page/components/pagination/collapse.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | pagination = html.Div( 5 | [ 6 | html.Div("Collapse long pagination objects using ellipsis"), 7 | dbc.Pagination(max_value=10, fully_expanded=False), 8 | html.Div("If space won't be saved, it won't be collapsed"), 9 | dbc.Pagination(max_value=5, fully_expanded=False), 10 | ] 11 | ) 12 | -------------------------------------------------------------------------------- /docs/components_page/components/input/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | text_input = html.Div( 5 | [ 6 | dbc.Input(id="input", placeholder="Type something...", type="text"), 7 | html.Br(), 8 | html.P(id="output"), 9 | ] 10 | ) 11 | 12 | 13 | @app.callback(Output("output", "children"), [Input("input", "value")]) 14 | def output_text(value): 15 | return value 16 | -------------------------------------------------------------------------------- /docs/components_page/components/input_group/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | input_group = html.Div( 5 | [ 6 | dbc.InputGroup([dbc.InputGroupText("Large"), dbc.Input()], size="lg"), 7 | html.Br(), 8 | dbc.InputGroup([dbc.InputGroupText("Default"), dbc.Input()]), 9 | html.Br(), 10 | dbc.InputGroup([dbc.InputGroupText("Small"), dbc.Input()], size="sm"), 11 | ] 12 | ) 13 | -------------------------------------------------------------------------------- /docs/templates/partials/scripts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/pagination.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | pagination = html.Div( 7 | [ 8 | make_subheading("Pagination", "pagination"), 9 | dbc.Pagination( 10 | max_value=10, 11 | fully_expanded=False, 12 | first_last=True, 13 | previous_next=True, 14 | ), 15 | ], 16 | className="mb-4", 17 | ) 18 | -------------------------------------------------------------------------------- /docs/components_page/components/badge/positioned.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | badge = dbc.Button( 4 | [ 5 | "Notifications", 6 | dbc.Badge( 7 | "99+", 8 | color="danger", 9 | pill=True, 10 | text_color="white", 11 | className="position-absolute top-0 start-100 translate-middle", 12 | ), 13 | ], 14 | color="primary", 15 | className="position-relative", 16 | ) 17 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | row = html.Div( 5 | [ 6 | dbc.Row(dbc.Col(html.Div("A single column"))), 7 | dbc.Row( 8 | [ 9 | dbc.Col(html.Div("One of three columns")), 10 | dbc.Col(html.Div("One of three columns")), 11 | dbc.Col(html.Div("One of three columns")), 12 | ] 13 | ), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /docs/components_page/components/tabs/labels_with_icons.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | tabs = dbc.Tabs( 5 | [ 6 | dbc.Tab( 7 | html.Div("This is the content of tab 1", className="p-4"), 8 | label="Tab 1", 9 | ), 10 | dbc.Tab( 11 | html.Div("This is the content of tab 2", className="p-4"), 12 | label="Tab 2", 13 | ), 14 | ], 15 | id="labelled-tabs", 16 | ) 17 | -------------------------------------------------------------------------------- /docs/components_page/components/spinner/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | spinners = html.Div( 5 | [ 6 | dbc.Spinner(color="primary"), 7 | dbc.Spinner(color="secondary"), 8 | dbc.Spinner(color="success"), 9 | dbc.Spinner(color="warning"), 10 | dbc.Spinner(color="danger"), 11 | dbc.Spinner(color="info"), 12 | dbc.Spinner(color="light"), 13 | dbc.Spinner(color="dark"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /docs/components_page/components/nav/fill.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | nav_contents = [ 5 | dbc.NavItem(dbc.NavLink("Active", href="#", active=True)), 6 | dbc.NavItem(dbc.NavLink("A much longer link label", href="#")), 7 | dbc.NavItem(dbc.NavLink("Link", href="#")), 8 | ] 9 | 10 | nav1 = dbc.Nav(nav_contents, pills=True, fill=True) 11 | 12 | nav2 = dbc.Nav(nav_contents, pills=True, justified=True) 13 | 14 | navs = html.Div([nav1, html.Hr(), nav2]) 15 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/custom_style.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | dropdown = dbc.DropdownMenu( 4 | [ 5 | dbc.DropdownMenuItem("Item 1"), 6 | dbc.DropdownMenuItem("Item 2"), 7 | dbc.DropdownMenuItem("Item 3"), 8 | ], 9 | label="Custom", 10 | className="m-1", 11 | toggle_style={ 12 | "textTransform": "uppercase", 13 | "background": "#FB79B3", 14 | }, 15 | toggleClassName="fst-italic border border-dark", 16 | ) 17 | -------------------------------------------------------------------------------- /docs/components_page/components/spinner/button.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | spinners = html.Div( 5 | [ 6 | dbc.Button( 7 | dbc.Spinner(size="sm"), 8 | color="primary", 9 | disabled=True, 10 | className="me-1", 11 | ), 12 | dbc.Button( 13 | [dbc.Spinner(size="sm"), " Loading..."], 14 | color="primary", 15 | disabled=True, 16 | ), 17 | ] 18 | ) 19 | -------------------------------------------------------------------------------- /docs/components_page/components/card/sizing/css.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | cards = dbc.Card( 5 | dbc.CardBody( 6 | [ 7 | html.H5("Custom CSS", className="card-title"), 8 | html.P( 9 | "This card has inline styles applied controlling the width. " 10 | "You could also apply the same styles with a custom CSS class." 11 | ), 12 | ] 13 | ), 14 | style={"width": "18rem"}, 15 | ) 16 | -------------------------------------------------------------------------------- /docs/static/js/v2-alert.js: -------------------------------------------------------------------------------- 1 | var migrationAlertContainer = document.getElementById('v2-alert-container'); 2 | 3 | if (!window.localStorage.getItem('dbc-v2-alert-seen')) { 4 | migrationAlertContainer.setAttribute('style', 'display:block'); 5 | } 6 | 7 | var migrationAlert = document.getElementById('v2-alert'); 8 | migrationAlert.addEventListener('closed.bs.alert', function () { 9 | window.localStorage.setItem('dbc-v2-alert-seen', 'true'); 10 | migrationAlertContainer.setAttribute('style', 'display:none'); 11 | }); 12 | -------------------------------------------------------------------------------- /examples/gallery/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This directory contains a collection of example apps that demonstrate usage of `dash-bootstrap-components`. Many of the apps have dependencies that are not dependencies of `dash-bootstrap-components` itself, each app has its own `requirements.txt` file containing these dependencies. You can easily install them with `pip install -r requirements.txt`. 4 | 5 | Apps are written for Python 3.6+, they may happen to work with older versions of Python, but this is not tested or guaranteed. 6 | -------------------------------------------------------------------------------- /docs/components_page/components/input/textarea.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | textareas = html.Div( 5 | [ 6 | dbc.Textarea(className="mb-3", placeholder="A Textarea"), 7 | dbc.Textarea( 8 | valid=True, 9 | size="sm", 10 | className="mb-3", 11 | placeholder="A small, valid Textarea", 12 | ), 13 | dbc.Textarea(invalid=True, size="lg", placeholder="A large, invalid Textarea"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /docs/components_page/components/card/header_footer.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | card = dbc.Card( 5 | [ 6 | dbc.CardHeader("This is the header"), 7 | dbc.CardBody( 8 | [ 9 | html.H4("Card title", className="card-title"), 10 | html.P("This is some card text", className="card-text"), 11 | ] 12 | ), 13 | dbc.CardFooter("This is the footer"), 14 | ], 15 | style={"width": "18rem"}, 16 | ) 17 | -------------------------------------------------------------------------------- /docs/templates/docs.html: -------------------------------------------------------------------------------- 1 | {% from "macros/sidenav.html" import sidenav %} 2 | {% from "macros/navbar.html" import navbar %} 3 | {% extends "base.html" %} 4 | {% block header %}{{ navbar("docs") }}{% endblock %} 5 | {% block body %} 6 |
7 |
8 |
9 | {{ sidenav(sidenav_items, sidenav_active, active_child) }} 10 |
11 |
{% block content %}{% endblock %}
12 |
13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | Before opening: 2 | 3 | - [Search for duplicate or closed issues](https://github.com/dbc-team/dash-bootstrap-components/issues?utf8=%E2%9C%93&q=is%3Aissue) 4 | - Read the [contributing guidelines](https://github.com/dbc-team/dash-bootstrap-components/blob/main/.github/CONTRIBUTING.md) 5 | 6 | Feature requests must include: 7 | 8 | - As much detail as possible for what we should add and why it's important to 9 | include it in Dash Bootstrap Components 10 | - Relevant links to prior art, screenshots, or live demos whenever possible 11 | -------------------------------------------------------------------------------- /docs/templates/partials/v2-alert.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # js artifacts 2 | node_modules 3 | lib 4 | demo-lib 5 | 6 | # testing 7 | .nox 8 | .pytest_cache 9 | 10 | # dash-bootstrap-components artifacts 11 | dash_bootstrap_components/bundle.js 12 | dash_bootstrap_components/metadata.json 13 | dash_bootstrap_components/_components/ 14 | 15 | # python build artifacts 16 | __pycache__ 17 | *.pyc 18 | dist 19 | py-dist 20 | *.egg-info 21 | 22 | # release artifacts 23 | changelog.tmp 24 | 25 | # generated documentation files 26 | docs/templates/generated/**/*.html 27 | 28 | # vendored example apps 29 | docs/examples/vendor 30 | -------------------------------------------------------------------------------- /docs/components_page/components/table/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | table_header = [html.Thead(html.Tr([html.Th("First Name"), html.Th("Last Name")]))] 5 | 6 | row1 = html.Tr([html.Td("Arthur"), html.Td("Dent")]) 7 | row2 = html.Tr([html.Td("Ford"), html.Td("Prefect")]) 8 | row3 = html.Tr([html.Td("Zaphod"), html.Td("Beeblebrox")]) 9 | row4 = html.Tr([html.Td("Trillian"), html.Td("Astra")]) 10 | 11 | table_body = [html.Tbody([row1, row2, row3, row4])] 12 | 13 | table = dbc.Table(table_header + table_body, bordered=True) 14 | -------------------------------------------------------------------------------- /src/private/types.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | const stringOrNumberPropType = PropTypes.oneOfType([ 4 | PropTypes.number, 5 | PropTypes.string 6 | ]); 7 | 8 | const columnPropType = PropTypes.oneOfType([ 9 | PropTypes.bool, 10 | PropTypes.string, 11 | PropTypes.number, 12 | PropTypes.shape({ 13 | size: PropTypes.oneOfType([ 14 | PropTypes.bool, 15 | PropTypes.number, 16 | PropTypes.string 17 | ]), 18 | order: stringOrNumberPropType, 19 | offset: stringOrNumberPropType 20 | }) 21 | ]); 22 | 23 | export {columnPropType}; 24 | -------------------------------------------------------------------------------- /docs/components_page/components/nav/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | nav = dbc.Nav( 4 | [ 5 | dbc.NavItem(dbc.NavLink("Active", active=True, href="#")), 6 | dbc.NavItem(dbc.NavLink("A link", href="#")), 7 | dbc.NavItem(dbc.NavLink("Another link", href="#")), 8 | dbc.NavItem(dbc.NavLink("Disabled", disabled=True, href="#")), 9 | dbc.DropdownMenu( 10 | [dbc.DropdownMenuItem("Item 1"), dbc.DropdownMenuItem("Item 2")], 11 | label="Dropdown", 12 | nav=True, 13 | ), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /src/private/BootstrapColors.js: -------------------------------------------------------------------------------- 1 | /* Reference: https://getbootstrap.com/docs/4.1/utilities/colors/ */ 2 | 3 | export const bootstrapColors = new Set([ 4 | 'primary', 5 | 'secondary', 6 | 'success', 7 | 'danger', 8 | 'warning', 9 | 'info', 10 | 'light', 11 | 'dark', 12 | 'white', 13 | 'transparent' 14 | ]); 15 | 16 | export const bootstrapTextColors = new Set([ 17 | 'primary', 18 | 'secondary', 19 | 'success', 20 | 'danger', 21 | 'warning', 22 | 'info', 23 | 'light', 24 | 'dark', 25 | 'muted', 26 | 'white', 27 | 'black-50', 28 | 'white-50' 29 | ]); 30 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/components_page/components/spinner/grow.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | spinners = html.Div( 5 | [ 6 | dbc.Spinner(color="primary", type="grow"), 7 | dbc.Spinner(color="secondary", type="grow"), 8 | dbc.Spinner(color="success", type="grow"), 9 | dbc.Spinner(color="warning", type="grow"), 10 | dbc.Spinner(color="danger", type="grow"), 11 | dbc.Spinner(color="info", type="grow"), 12 | dbc.Spinner(color="light", type="grow"), 13 | dbc.Spinner(color="dark", type="grow"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /docs/static/loading.css: -------------------------------------------------------------------------------- 1 | ._dash-loading { 2 | margin: auto; 3 | color: transparent; 4 | width: 2rem; 5 | height: 2rem; 6 | text-align: center; 7 | } 8 | 9 | ._dash-loading::after { 10 | content: ''; 11 | display: inline-block; 12 | width: 2rem; 13 | height: 2rem; 14 | color: var(--bs-secondary); 15 | vertical-align: text-bottom; 16 | border: 0.25em solid currentColor; 17 | border-right-color: transparent; 18 | border-radius: 50%; 19 | -webkit-animation: spinner-border 0.75s linear infinite; 20 | animation: spinner-border 0.75s linear infinite; 21 | margin-top: 2rem; 22 | } 23 | -------------------------------------------------------------------------------- /docs/components_page/components/button/usage.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | button = html.Div( 5 | [ 6 | dbc.Button("Click me", id="example-button", className="me-2", n_clicks=0), 7 | html.Span(id="example-output", style={"verticalAlign": "middle"}), 8 | ] 9 | ) 10 | 11 | 12 | @app.callback( 13 | Output("example-output", "children"), [Input("example-button", "n_clicks")] 14 | ) 15 | def on_button_click(n): 16 | if n is None: 17 | return "Not clicked." 18 | else: 19 | return f"Clicked {n} times." 20 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/width.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | row = html.Div( 5 | [ 6 | dbc.Row(dbc.Col(html.Div("A single, half-width column"), width=6)), 7 | dbc.Row(dbc.Col(html.Div("An automatically sized column"), width="auto")), 8 | dbc.Row( 9 | [ 10 | dbc.Col(html.Div("One of three columns"), width=3), 11 | dbc.Col(html.Div("One of three columns")), 12 | dbc.Col(html.Div("One of three columns"), width=3), 13 | ] 14 | ), 15 | ] 16 | ) 17 | -------------------------------------------------------------------------------- /docs/components_page/components/popover/popover_components.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | popovers = html.Div( 5 | [ 6 | dbc.Button( 7 | "Click Me", 8 | id="component-target", 9 | n_clicks=0, 10 | ), 11 | dbc.Popover( 12 | [ 13 | dbc.PopoverHeader("Popover header"), 14 | dbc.PopoverBody("And here's some amazing content. Cool!"), 15 | ], 16 | target="component-target", 17 | trigger="click", 18 | ), 19 | ] 20 | ) 21 | -------------------------------------------------------------------------------- /docs/components_page/components/spinner/loading.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import dash_bootstrap_components as dbc 4 | from dash import Input, Output, html 5 | 6 | loading_spinner = html.Div( 7 | [ 8 | dbc.Button("Load", id="loading-button", n_clicks=0), 9 | dbc.Spinner(html.Div(id="loading-output")), 10 | ] 11 | ) 12 | 13 | 14 | @app.callback( 15 | Output("loading-output", "children"), [Input("loading-button", "n_clicks")] 16 | ) 17 | def load_output(n): 18 | if n: 19 | time.sleep(1) 20 | return f"Output loaded {n} times" 21 | return "Output not reloaded yet" 22 | -------------------------------------------------------------------------------- /docs/templates/macros/theme-explorer-navbar.html: -------------------------------------------------------------------------------- 1 | {% macro theme_explorer_navbar() -%} 2 | 20 | {%- endmacro %} 21 | -------------------------------------------------------------------------------- /docs/components_page/components/badge/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | badges = html.Div( 5 | [ 6 | html.H1(["Example heading", dbc.Badge("New", className="ms-1")]), 7 | html.H2(["Example heading", dbc.Badge("New", className="ms-1")]), 8 | html.H3(["Example heading", dbc.Badge("New", className="ms-1")]), 9 | html.H4(["Example heading", dbc.Badge("New", className="ms-1")]), 10 | html.H5(["Example heading", dbc.Badge("New", className="ms-1")]), 11 | html.H6(["Example heading", dbc.Badge("New", className="ms-1")]), 12 | ] 13 | ) 14 | -------------------------------------------------------------------------------- /docs/components_page/components/tabs/style.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | tabs = html.Div( 5 | [ 6 | dbc.Tabs( 7 | [ 8 | dbc.Tab(label="Tab 1", tab_style={"marginLeft": "auto"}), 9 | dbc.Tab(label="Tab 2", label_style={"color": "#00AEF9"}), 10 | ] 11 | ), 12 | html.Br(), 13 | dbc.Tabs( 14 | [ 15 | dbc.Tab(label="Tab 1", tabClassName="ms-auto"), 16 | dbc.Tab(label="Tab 2", labelClassName="text-success"), 17 | ] 18 | ), 19 | ] 20 | ) 21 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/collapse.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | collapse = html.Div( 7 | [ 8 | make_subheading("Collapse", "collapse"), 9 | html.Div( 10 | [ 11 | dbc.Button("Open collapse", id="collapse-button", className="mb-2"), 12 | dbc.Collapse( 13 | dbc.Card(dbc.CardBody("This content is hidden in the collapse")), 14 | id="collapse", 15 | ), 16 | ] 17 | ), 18 | ], 19 | className="mb-4", 20 | ) 21 | -------------------------------------------------------------------------------- /docs/components_page/components/alert/content.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | alert = dbc.Alert( 5 | [ 6 | html.H4("Well done!", className="alert-heading"), 7 | html.P( 8 | "This is a success alert with loads of extra text in it. So much " 9 | "that you can see how spacing within an alert works with this " 10 | "kind of content." 11 | ), 12 | html.Hr(), 13 | html.P( 14 | "Let's put some more text down here, but remove the bottom margin", 15 | className="mb-0", 16 | ), 17 | ] 18 | ) 19 | -------------------------------------------------------------------------------- /docs/components_page/components/accordion/flush.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | accordion = html.Div( 5 | dbc.Accordion( 6 | [ 7 | dbc.AccordionItem( 8 | "This is the content of the first section", title="Item 1" 9 | ), 10 | dbc.AccordionItem( 11 | "This is the content of the second section", title="Item 2" 12 | ), 13 | dbc.AccordionItem( 14 | "This is the content of the third section", title="Item 3" 15 | ), 16 | ], 17 | flush=True, 18 | ), 19 | ) 20 | -------------------------------------------------------------------------------- /docs/components_page/components/alert/link.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | alerts = html.Div( 5 | [ 6 | dbc.Alert( 7 | [ 8 | "This is a primary alert with an ", 9 | html.A("example link", href="#", className="alert-link"), 10 | ], 11 | color="primary", 12 | ), 13 | dbc.Alert( 14 | [ 15 | "This is a danger alert with an ", 16 | html.A("example link", href="#", className="alert-link"), 17 | ], 18 | color="danger", 19 | ), 20 | ] 21 | ) 22 | -------------------------------------------------------------------------------- /docs/components_page/components/accordion/collapsed.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | accordion = html.Div( 5 | dbc.Accordion( 6 | [ 7 | dbc.AccordionItem( 8 | "This is the content of the first section", title="Item 1" 9 | ), 10 | dbc.AccordionItem( 11 | "This is the content of the second section", title="Item 2" 12 | ), 13 | dbc.AccordionItem( 14 | "This is the content of the third section", title="Item 3" 15 | ), 16 | ], 17 | start_collapsed=True, 18 | ), 19 | ) 20 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/simple_stack.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | stack = html.Div( 5 | [ 6 | dbc.Stack( 7 | [ 8 | html.Div("This stack has no gaps"), 9 | html.Div("Next item"), 10 | html.Div("Last item"), 11 | ] 12 | ), 13 | html.Hr(), 14 | dbc.Stack( 15 | [ 16 | html.Div("This stack has gaps"), 17 | html.Div("Next item"), 18 | html.Div("Last item"), 19 | ], 20 | gap=3, 21 | ), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/popover.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | popover = html.Div( 7 | [ 8 | make_subheading("Popover", "popover"), 9 | dbc.Button("Click to toggle popover", id="popover-target", color="danger"), 10 | dbc.Popover( 11 | [ 12 | dbc.PopoverHeader("Popover header"), 13 | dbc.PopoverBody("Popover body"), 14 | ], 15 | id="popover", 16 | is_open=False, 17 | target="popover-target", 18 | ), 19 | ], 20 | className="mb-4", 21 | ) 22 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | items = [ 5 | dbc.DropdownMenuItem("First"), 6 | dbc.DropdownMenuItem(divider=True), 7 | dbc.DropdownMenuItem("Second"), 8 | ] 9 | 10 | dropdown = html.Div( 11 | [ 12 | dbc.DropdownMenu( 13 | label="large dropdown", 14 | size="lg", 15 | children=items, 16 | className="mb-3", 17 | ), 18 | dbc.DropdownMenu(label="normal dropdown", children=items, className="mb-3"), 19 | dbc.DropdownMenu(label="small dropdown", size="sm", children=items), 20 | ] 21 | ) 22 | -------------------------------------------------------------------------------- /src/components/form/__tests__/Form.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import Form from '../Form'; 9 | 10 | describe('Form', () => { 11 | test('renders a form', () => { 12 | const form = render(
); 13 | 14 | expect(form.container.querySelector('form')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const form = render(Some form content
); 19 | 20 | expect(form.container).toHaveTextContent('Some form content'); 21 | }); 22 | 23 | // TODO: integration tests for form submit actions? 24 | }); 25 | -------------------------------------------------------------------------------- /docs/components_page/components/navbar/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | navbar = dbc.NavbarSimple( 4 | children=[ 5 | dbc.NavItem(dbc.NavLink("Page 1", href="#")), 6 | dbc.DropdownMenu( 7 | children=[ 8 | dbc.DropdownMenuItem("More pages", header=True), 9 | dbc.DropdownMenuItem("Page 2", href="#"), 10 | dbc.DropdownMenuItem("Page 3", href="#"), 11 | ], 12 | nav=True, 13 | in_navbar=True, 14 | label="More", 15 | ), 16 | ], 17 | brand="NavbarSimple", 18 | brand_href="#", 19 | color="primary", 20 | dark=True, 21 | ) 22 | -------------------------------------------------------------------------------- /src/components/card/__tests__/CardBody.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import CardBody from '../CardBody'; 9 | 10 | describe('CardBody', () => { 11 | test('renders a div with class "card-body"', () => { 12 | const cardBody = render(); 13 | 14 | expect(cardBody.container.querySelector('div.card-body')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const cardBody = render(Some card body content); 19 | 20 | expect(cardBody.container).toHaveTextContent('Some card body content'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /src/components/nav/__tests__/NavItem.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import NavItem from '../NavItem'; 9 | 10 | describe('NavItem', () => { 11 | test('renders a div with class "nav-item"', () => { 12 | const navbarBrand = render(); 13 | 14 | expect(navbarBrand.container.querySelector('div.nav-item')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const navbarBrand = render(Some nav item content); 19 | 20 | expect(navbarBrand.container).toHaveTextContent('Some nav item content'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /docs/components_page/components/form/inline.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | form = dbc.Form( 4 | dbc.Row( 5 | [ 6 | dbc.Label("Email", width="auto"), 7 | dbc.Col( 8 | dbc.Input(type="email", placeholder="Enter email"), 9 | className="me-3", 10 | ), 11 | dbc.Label("Password", width="auto"), 12 | dbc.Col( 13 | dbc.Input(type="password", placeholder="Enter password"), 14 | className="me-3", 15 | ), 16 | dbc.Col(dbc.Button("Submit", color="primary"), width="auto"), 17 | ], 18 | className="g-2", 19 | ) 20 | ) 21 | -------------------------------------------------------------------------------- /docs/components_page/components/badge/color.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | badges = html.Span( 5 | [ 6 | dbc.Badge("Primary", color="primary", className="me-1"), 7 | dbc.Badge("Secondary", color="secondary", className="me-1"), 8 | dbc.Badge("Success", color="success", className="me-1"), 9 | dbc.Badge("Warning", color="warning", className="me-1"), 10 | dbc.Badge("Danger", color="danger", className="me-1"), 11 | dbc.Badge("Info", color="info", className="me-1"), 12 | dbc.Badge("Light", text_color="dark", color="light", className="me-1"), 13 | dbc.Badge("Dark", color="dark"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Tell us about a feature you would like to see in Dash Bootstrap Components 4 | --- 5 | 6 | Before opening: 7 | 8 | - [Search for duplicate or closed issues](https://github.com/dbc-team/dash-bootstrap-components/issues?utf8=%E2%9C%93&q=is%3Aissue) 9 | - Read the [contributing guidelines](https://github.com/dbc-team/dash-bootstrap-components/blob/main/.github/CONTRIBUTING.md) 10 | 11 | Feature requests must include: 12 | 13 | - As much detail as possible for what we should add and why it's important to 14 | include it in Dash Bootstrap Components 15 | - Relevant links to prior art, screenshots, or live demos whenever possible 16 | -------------------------------------------------------------------------------- /docs/components_page/components/button_group/size.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | button_groups = html.Div( 5 | [ 6 | dbc.ButtonGroup( 7 | [dbc.Button("Left"), dbc.Button("Middle"), dbc.Button("Right")], 8 | size="lg", 9 | className="me-1", 10 | ), 11 | dbc.ButtonGroup( 12 | [dbc.Button("Left"), dbc.Button("Middle"), dbc.Button("Right")], 13 | size="md", 14 | className="me-1", 15 | ), 16 | dbc.ButtonGroup( 17 | [dbc.Button("Left"), dbc.Button("Middle"), dbc.Button("Right")], 18 | size="sm", 19 | ), 20 | ] 21 | ) 22 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/toast.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | toast = html.Div( 7 | [ 8 | make_subheading("Toast", "toast"), 9 | dbc.Button( 10 | "Open toast", 11 | id="auto-toast-toggle", 12 | color="primary", 13 | className="mb-3", 14 | ), 15 | dbc.Toast( 16 | html.P("This is the content of the toast", className="mb-0"), 17 | id="auto-toast", 18 | header="This is the header", 19 | icon="primary", 20 | duration=4000, 21 | ), 22 | ], 23 | className="mb-2", 24 | ) 25 | -------------------------------------------------------------------------------- /src/components/card/__tests__/CardGroup.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import CardGroup from '../CardGroup'; 9 | 10 | describe('CardGroup', () => { 11 | test('renders a div with class "card-group"', () => { 12 | const cardGroup = render(); 13 | 14 | expect(cardGroup.container.querySelector('div.card-group')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const cardGroup = render(Some card group content); 19 | 20 | expect(cardGroup.container).toHaveTextContent('Some card group content'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /src/components/modal/__tests__/ModalBody.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import ModalBody from '../ModalBody'; 9 | 10 | describe('ModalBody', () => { 11 | test('renders a div with class "modal-body"', () => { 12 | const modalBody = render(); 13 | 14 | expect(modalBody.container.querySelector('div.modal-body')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const modalBody = render(Some modal body content); 19 | 20 | expect(modalBody.container).toHaveTextContent('Some modal body content'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/breadcrumb.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | breadcrumb = html.Div( 7 | [ 8 | make_subheading("Breadcrumb", "breadcrumb"), 9 | dbc.Breadcrumb( 10 | items=[ 11 | {"label": "Docs", "href": "/docs", "external_link": True}, 12 | { 13 | "label": "Components", 14 | "href": "/docs/components", 15 | "external_link": True, 16 | }, 17 | {"label": "Breadcrumb", "active": True}, 18 | ], 19 | ), 20 | ], 21 | className="mb-4", 22 | ) 23 | -------------------------------------------------------------------------------- /docs/components_page/components/accordion/always_open.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | accordion = html.Div( 5 | dbc.Accordion( 6 | [ 7 | dbc.AccordionItem( 8 | "This is the content of the first section", 9 | title="Item 1", 10 | ), 11 | dbc.AccordionItem( 12 | "This is the content of the second section", 13 | title="Item 2", 14 | ), 15 | dbc.AccordionItem( 16 | "This is the content of the third section", 17 | title="Item 3", 18 | ), 19 | ], 20 | always_open=True, 21 | ) 22 | ) 23 | -------------------------------------------------------------------------------- /docs/components_page/components/card/ttl.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | card = dbc.Card( 5 | dbc.CardBody( 6 | [ 7 | html.H4("Title", className="card-title"), 8 | html.H6("Card subtitle", className="card-subtitle"), 9 | html.P( 10 | "Some quick example text to build on the card title and make " 11 | "up the bulk of the card's content.", 12 | className="card-text", 13 | ), 14 | dbc.CardLink("Card link", href="#"), 15 | dbc.CardLink("External link", href="https://google.com"), 16 | ] 17 | ), 18 | style={"width": "18rem"}, 19 | ) 20 | -------------------------------------------------------------------------------- /docs/components_page/components/input_group/button.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output 3 | 4 | input_group = dbc.InputGroup( 5 | [ 6 | dbc.Button("Random name", id="input-group-button", n_clicks=0), 7 | dbc.Input(id="input-group-button-input", placeholder="name"), 8 | ] 9 | ) 10 | 11 | 12 | @app.callback( 13 | Output("input-group-button-input", "value"), 14 | [Input("input-group-button", "n_clicks")], 15 | ) 16 | def on_button_click(n_clicks): 17 | if n_clicks: 18 | names = ["Arthur Dent", "Ford Prefect", "Trillian Astra"] 19 | which = n_clicks % len(names) 20 | return names[which] 21 | else: 22 | return "" 23 | -------------------------------------------------------------------------------- /docs/components_page/components/tooltip/placement.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | 5 | def make_button(placement): 6 | return dbc.Button( 7 | f"Tooltip on {placement}", 8 | id=f"tooltip-target-{placement}", 9 | className="mx-2", 10 | n_clicks=0, 11 | ) 12 | 13 | 14 | def make_tooltip(placement): 15 | return dbc.Tooltip( 16 | f"Tooltip on {placement}", 17 | target=f"tooltip-target-{placement}", 18 | placement=placement, 19 | ) 20 | 21 | 22 | tooltips = html.Div( 23 | [make_button(p) for p in ["top", "left", "right", "bottom"]] 24 | + [make_tooltip(p) for p in ["top", "left", "right", "bottom"]] 25 | ) 26 | -------------------------------------------------------------------------------- /docs/components_page/components/tooltip/tooltip.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | tooltip = html.Div( 5 | [ 6 | html.P( 7 | [ 8 | "I wonder what ", 9 | html.Span( 10 | "floccinaucinihilipilification", 11 | id="tooltip-target", 12 | style={"textDecoration": "underline", "cursor": "pointer"}, 13 | ), 14 | " means?", 15 | ] 16 | ), 17 | dbc.Tooltip( 18 | "Noun: rare, " "the action or habit of estimating something as worthless.", 19 | target="tooltip-target", 20 | ), 21 | ] 22 | ) 23 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/colors.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | list_group = dbc.ListGroup( 4 | [ 5 | dbc.ListGroupItem("No color applied"), 6 | dbc.ListGroupItem("The primary item", color="primary"), 7 | dbc.ListGroupItem("A secondary item", color="secondary"), 8 | dbc.ListGroupItem("A successful item", color="success"), 9 | dbc.ListGroupItem("A warning item", color="warning"), 10 | dbc.ListGroupItem("A dangerous item", color="danger"), 11 | dbc.ListGroupItem("An informative item", color="info"), 12 | dbc.ListGroupItem("A light item", color="light"), 13 | dbc.ListGroupItem("A dark item", color="dark"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /src/components/card/__tests__/CardImg.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import CardImg from '../CardImg'; 9 | 10 | describe('CardImg', () => { 11 | test('renders a div with class "card-img"', () => { 12 | const cardImg = render(); 13 | 14 | expect(cardImg.container.querySelector('img.card-img')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const cardImg = render(); 19 | 20 | expect(cardImg.container.querySelector('.card-img')).toHaveAttribute( 21 | 'src', 22 | '/test-image.jpg' 23 | ); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /docs/components_page/components/alert/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | alerts = html.Div( 5 | [ 6 | dbc.Alert("This is a primary alert", color="primary"), 7 | dbc.Alert("This is a secondary alert", color="secondary"), 8 | dbc.Alert("This is a success alert! Well done!", color="success"), 9 | dbc.Alert("This is a warning alert... be careful...", color="warning"), 10 | dbc.Alert("This is a danger alert. Scary!", color="danger"), 11 | dbc.Alert("This is an info alert. Good to know!", color="info"), 12 | dbc.Alert("This is a light alert", color="light"), 13 | dbc.Alert("This is a dark alert", color="dark"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /docs/components_page/components/card/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | card = dbc.Card( 5 | [ 6 | dbc.CardImg(src="/static/images/placeholder286x180.png", top=True), 7 | dbc.CardBody( 8 | [ 9 | html.H4("Card title", className="card-title"), 10 | html.P( 11 | "Some quick example text to build on the card title and " 12 | "make up the bulk of the card's content.", 13 | className="card-text", 14 | ), 15 | dbc.Button("Go somewhere", color="primary"), 16 | ] 17 | ), 18 | ], 19 | style={"width": "18rem"}, 20 | ) 21 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/horizontal.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | list_group = html.Div( 5 | [ 6 | dbc.ListGroup( 7 | [ 8 | dbc.ListGroupItem("Item 1"), 9 | dbc.ListGroupItem("Item 2"), 10 | dbc.ListGroupItem("Item 3"), 11 | ], 12 | horizontal=True, 13 | className="mb-2", 14 | ), 15 | dbc.ListGroup( 16 | [ 17 | dbc.ListGroupItem("Item 1"), 18 | dbc.ListGroupItem("Item 2"), 19 | dbc.ListGroupItem("Item 3"), 20 | ], 21 | horizontal="lg", 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /docs/templates/macros/example-navbar.html: -------------------------------------------------------------------------------- 1 | {% macro example_navbar() -%} 2 | 20 | {%- endmacro %} 21 | -------------------------------------------------------------------------------- /docs/components_page/components/carousel/captions.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | carousel = dbc.Carousel( 4 | items=[ 5 | { 6 | "key": "1", 7 | "src": "/static/images/slide1.svg", 8 | "header": "With header ", 9 | "caption": "and caption", 10 | }, 11 | { 12 | "key": "2", 13 | "src": "/static/images/slide2.svg", 14 | "header": "With header only", 15 | "caption": "", 16 | }, 17 | { 18 | "key": "3", 19 | "src": "/static/images/slide3.svg", 20 | "header": "", 21 | "caption": "This slide has a caption only", 22 | }, 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /docs/components_page/components/table/helper_multi.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | import pandas as pd 3 | 4 | df = pd.DataFrame( 5 | { 6 | ("Score", "Max"): { 7 | "Arthur Dent": 6.0, 8 | "Ford Prefect": 4.0, 9 | "Zaphod Beeblebrox": 1.0, 10 | "Trillian Astra": 3.0, 11 | }, 12 | ("Score", "Average"): { 13 | "Arthur Dent": 2.0, 14 | "Ford Prefect": 2.0, 15 | "Zaphod Beeblebrox": 0.7, 16 | "Trillian Astra": 1.9, 17 | }, 18 | } 19 | ) 20 | df.index.set_names("Name", inplace=True) 21 | 22 | table = dbc.Table.from_dataframe( 23 | df, striped=True, bordered=True, hover=True, index=True 24 | ) 25 | -------------------------------------------------------------------------------- /webpack/moduleDefinition.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var directories = require('./directories'); 4 | 5 | module.exports = { 6 | noParse: /node_modules\/json-schema\/lib\/validate\.js/, // used to get `request` to work: https://github.com/request/request/issues/1920#issuecomment-171246043 7 | rules: [ 8 | { 9 | test: /\.json$/, 10 | loader: 'json-loader' 11 | }, 12 | { 13 | test: /\.jsx?$/, 14 | include: [directories.SRC, directories.DEMO], 15 | loader: 'babel-loader' 16 | }, 17 | { 18 | test: /\.css$/, 19 | use: [ 20 | { 21 | loader: 'style-loader' 22 | }, 23 | { 24 | loader: 'css-loader' 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /docs/components_page/components/button/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | buttons = html.Div( 5 | [ 6 | dbc.Button("Primary", color="primary", className="me-1"), 7 | dbc.Button("Secondary", color="secondary", className="me-1"), 8 | dbc.Button("Success", color="success", className="me-1"), 9 | dbc.Button("Warning", color="warning", className="me-1"), 10 | dbc.Button("Danger", color="danger", className="me-1"), 11 | dbc.Button("Info", color="info", className="me-1"), 12 | dbc.Button("Light", color="light", className="me-1"), 13 | dbc.Button("Dark", color="dark", className="me-1"), 14 | dbc.Button("Link", color="link"), 15 | ] 16 | ) 17 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/content.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | dropdown = dbc.DropdownMenu( 5 | [ 6 | dbc.DropdownMenuItem("Header", header=True), 7 | dbc.DropdownMenuItem("An item"), 8 | dbc.DropdownMenuItem(divider=True), 9 | dbc.DropdownMenuItem("Active and disabled", header=True), 10 | dbc.DropdownMenuItem("Active item", active=True), 11 | dbc.DropdownMenuItem("Disabled item", disabled=True), 12 | dbc.DropdownMenuItem(divider=True), 13 | html.P( 14 | "You can have other content here like text if you like.", 15 | className="text-muted px-4 mt-4", 16 | ), 17 | ], 18 | label="Menu", 19 | ) 20 | -------------------------------------------------------------------------------- /docs/components_page/components/tabs/active_style.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | tabs = html.Div( 5 | [ 6 | dbc.Tabs( 7 | [ 8 | dbc.Tab( 9 | label="tab 1", 10 | active_tab_style={"textTransform": "uppercase"}, 11 | ), 12 | dbc.Tab(label="tab 2", active_label_style={"color": "#FB79B3"}), 13 | ] 14 | ), 15 | html.Br(), 16 | dbc.Tabs( 17 | [ 18 | dbc.Tab(label="Tab 1", activeTabClassName="fw-bold fst-italic"), 19 | dbc.Tab(label="Tab 2", activeLabelClassName="text-success"), 20 | ] 21 | ), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /docs/components_page/components/carousel/dark.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | carousel = dbc.Carousel( 4 | items=[ 5 | { 6 | "key": "1", 7 | "src": "/static/images/slide1.svg", 8 | "header": "With header ", 9 | "caption": "and caption", 10 | }, 11 | { 12 | "key": "2", 13 | "src": "/static/images/slide2.svg", 14 | "header": "With header only", 15 | "caption": "", 16 | }, 17 | { 18 | "key": "3", 19 | "src": "/static/images/slide3.svg", 20 | "header": "", 21 | "caption": "This slide has a caption only", 22 | }, 23 | ], 24 | variant="dark", 25 | ) 26 | -------------------------------------------------------------------------------- /docs/components_page/components/progress/animated.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | progress = html.Div( 5 | [ 6 | dbc.Progress(value=80, id="animated-progress", animated=False, striped=True), 7 | dbc.Button( 8 | "Toggle animation", 9 | id="animation-toggle", 10 | className="mt-3", 11 | n_clicks=0, 12 | ), 13 | ] 14 | ) 15 | 16 | 17 | @app.callback( 18 | Output("animated-progress", "animated"), 19 | [Input("animation-toggle", "n_clicks")], 20 | [State("animated-progress", "animated")], 21 | ) 22 | def toggle_animation(n, animated): 23 | if n: 24 | return not animated 25 | return animated 26 | -------------------------------------------------------------------------------- /docs/components_page/components/placeholder/color.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | placeholder = html.Div( 5 | [ 6 | dbc.Placeholder(color="primary", className="me-1 mt-1 w-100"), 7 | dbc.Placeholder(color="secondary", className="me-1 mt-1 w-100"), 8 | dbc.Placeholder(color="success", className="me-1 mt-1 w-100"), 9 | dbc.Placeholder(color="warning", className="me-1 mt-1 w-100"), 10 | dbc.Placeholder(color="danger", className="me-1 mt-1 w-100"), 11 | dbc.Placeholder(color="info", className="me-1 mt-1 w-100"), 12 | dbc.Placeholder(color="light", className="me-1 mt-1 w-100"), 13 | dbc.Placeholder(color="dark", className="me-1 mt-1 w-100"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /src/components/card/__tests__/CardFooter.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import CardFooter from '../CardFooter'; 9 | 10 | describe('CardFooter', () => { 11 | test('renders a div with class "card-footer"', () => { 12 | const cardFooter = render(); 13 | 14 | expect(cardFooter.container.querySelector('div.card-footer')).not.toBe( 15 | null 16 | ); 17 | }); 18 | 19 | test('renders its content', () => { 20 | const cardFooter = render( 21 | Some card footer content 22 | ); 23 | 24 | expect(cardFooter.container).toHaveTextContent('Some card footer content'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/components/card/__tests__/CardHeader.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import CardHeader from '../CardHeader'; 9 | 10 | describe('CardHeader', () => { 11 | test('renders a div with class "card-header"', () => { 12 | const cardHeader = render(); 13 | 14 | expect(cardHeader.container.querySelector('div.card-header')).not.toBe( 15 | null 16 | ); 17 | }); 18 | 19 | test('renders its content', () => { 20 | const cardHeader = render( 21 | Some card header content 22 | ); 23 | 24 | expect(cardHeader.container).toHaveTextContent('Some card header content'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/components/modal/__tests__/ModalTitle.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import ModalTitle from '../ModalTitle'; 9 | 10 | describe('ModalTitle', () => { 11 | test('renders a div with class "modal-Title"', () => { 12 | const modalTitle = render(); 13 | 14 | expect(modalTitle.container.querySelector('div.modal-title')).not.toBe( 15 | null 16 | ); 17 | }); 18 | 19 | test('renders its content', () => { 20 | const modalTitle = render( 21 | Some modal title content 22 | ); 23 | 24 | expect(modalTitle.container).toHaveTextContent('Some modal title content'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /docs/components_page/components/alert/auto_dismiss.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | alert = html.Div( 5 | [ 6 | dbc.Button("Toggle", id="alert-toggle-auto", className="me-1", n_clicks=0), 7 | html.Hr(), 8 | dbc.Alert( 9 | "Hello! I am an auto-dismissing alert!", 10 | id="alert-auto", 11 | is_open=True, 12 | duration=4000, 13 | ), 14 | ] 15 | ) 16 | 17 | 18 | @app.callback( 19 | Output("alert-auto", "is_open"), 20 | [Input("alert-toggle-auto", "n_clicks")], 21 | [State("alert-auto", "is_open")], 22 | ) 23 | def toggle_alert(n, is_open): 24 | if n: 25 | return not is_open 26 | return is_open 27 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/card.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | cards = html.Div( 7 | [ 8 | make_subheading("Card", "card"), 9 | dbc.Card( 10 | [ 11 | dbc.CardHeader("This is the header"), 12 | dbc.CardBody( 13 | [ 14 | html.H4("Card title", className="card-title"), 15 | html.P("This is some card text", className="card-text"), 16 | ] 17 | ), 18 | dbc.CardFooter("This is the footer"), 19 | ], 20 | style={"width": "18rem"}, 21 | ), 22 | ], 23 | className="mb-4", 24 | ) 25 | -------------------------------------------------------------------------------- /docs/components_page/components/placeholder/loading.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import dash_bootstrap_components as dbc 4 | from dash import Input, Output, html 5 | 6 | placeholder = html.Div( 7 | [ 8 | dbc.Button("Load", id="loading-placeholder-button", n_clicks=0), 9 | dbc.Placeholder( 10 | html.Div(id="loading-placeholder-output"), 11 | className="w-100", 12 | animation="wave", 13 | ), 14 | ], 15 | ) 16 | 17 | 18 | @app.callback( 19 | Output("loading-placeholder-output", "children"), 20 | [Input("loading-placeholder-button", "n_clicks")], 21 | ) 22 | def load_output(n): 23 | if n: 24 | time.sleep(2) 25 | return f"Output loaded {n} times" 26 | return "Output not reloaded yet" 27 | -------------------------------------------------------------------------------- /docs/components_page/components/tabs/active_tab.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | tabs = html.Div( 5 | [ 6 | dbc.Tabs( 7 | [ 8 | dbc.Tab(label="Tab 1", tab_id="tab-1"), 9 | dbc.Tab(label="Tab 2", tab_id="tab-2"), 10 | ], 11 | id="tabs", 12 | active_tab="tab-1", 13 | ), 14 | html.Div(id="content"), 15 | ] 16 | ) 17 | 18 | 19 | @app.callback(Output("content", "children"), [Input("tabs", "active_tab")]) 20 | def switch_tab(at): 21 | if at == "tab-1": 22 | return tab1_content 23 | elif at == "tab-2": 24 | return tab2_content 25 | return html.P("This shouldn't ever be displayed...") 26 | -------------------------------------------------------------------------------- /docs/components_page/components/tabs/card.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | card = dbc.Card( 5 | [ 6 | dbc.CardHeader( 7 | dbc.Tabs( 8 | [ 9 | dbc.Tab(label="Tab 1", tab_id="tab-1"), 10 | dbc.Tab(label="Tab 2", tab_id="tab-2"), 11 | ], 12 | id="card-tabs", 13 | active_tab="tab-1", 14 | ) 15 | ), 16 | dbc.CardBody(html.P(id="card-content", className="card-text")), 17 | ] 18 | ) 19 | 20 | 21 | @app.callback(Output("card-content", "children"), [Input("card-tabs", "active_tab")]) 22 | def tab_content(active_tab): 23 | return "This is tab {}".format(active_tab) 24 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/alignment.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | items = [ 4 | dbc.DropdownMenuItem("Action"), 5 | dbc.DropdownMenuItem("Another action"), 6 | dbc.DropdownMenuItem("Something else here"), 7 | dbc.DropdownMenuItem(divider=True), 8 | dbc.DropdownMenuItem("Something else here after the divider"), 9 | ] 10 | 11 | dropdown = dbc.Row( 12 | [ 13 | dbc.Col( 14 | dbc.DropdownMenu( 15 | label="Left-aligned menu (default)", 16 | children=items, 17 | align_end=False, 18 | ) 19 | ), 20 | dbc.Col( 21 | dbc.DropdownMenu(label="Right-aligned menu", children=items, align_end=True) 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /docs/components_page/components/index/simple.py: -------------------------------------------------------------------------------- 1 | # 1. Import Dash 2 | import dash 3 | import dash_bootstrap_components as dbc 4 | 5 | # 2. Create a Dash app instance 6 | app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP]) 7 | 8 | # 3. Add the example to the app's layout 9 | # First we copy the snippet from the docs 10 | badge = dbc.Button( 11 | [ 12 | "Notifications", 13 | dbc.Badge("4", color="light", text_color="primary", className="ms-1"), 14 | ], 15 | color="primary", 16 | ) 17 | 18 | # Then we incorporate the snippet into our layout. 19 | # This example keeps it simple and just wraps it in a Container 20 | app.layout = dbc.Container(badge, fluid=True) 21 | 22 | # 5. Start the Dash server 23 | if __name__ == "__main__": 24 | app.run() 25 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/horizontal_stack.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | stack = html.Div( 5 | [ 6 | dbc.Stack( 7 | [ 8 | html.Div("Horizontal"), 9 | html.Div("Stack"), 10 | html.Div("Without"), 11 | html.Div("Gaps"), 12 | ], 13 | direction="horizontal", 14 | ), 15 | html.Hr(), 16 | dbc.Stack( 17 | [ 18 | html.Div("Horizontal"), 19 | html.Div("Stack"), 20 | html.Div("With"), 21 | html.Div("Gaps"), 22 | ], 23 | direction="horizontal", 24 | gap=3, 25 | ), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /src/components/popover/__tests__/PopoverBody.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import PopoverBody from '../PopoverBody'; 9 | 10 | describe('PopoverBody', () => { 11 | test('renders an element with class "popover-body"', () => { 12 | const popoverBody = render(); 13 | 14 | expect(popoverBody.container.querySelector('.popover-body')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const popoverBody = render( 19 | Some popover body content 20 | ); 21 | 22 | expect(popoverBody.container).toHaveTextContent( 23 | 'Some popover body content' 24 | ); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /docs/components_page/components/modal/fullscreen.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | modal = html.Div( 5 | [ 6 | dbc.Button("Open modal", id="open-fs"), 7 | dbc.Modal( 8 | [ 9 | dbc.ModalHeader(dbc.ModalTitle("Fullscreen modal")), 10 | dbc.ModalBody("Wow this thing takes up a lot of space..."), 11 | ], 12 | id="modal-fs", 13 | fullscreen=True, 14 | ), 15 | ] 16 | ) 17 | 18 | 19 | @app.callback( 20 | Output("modal-fs", "is_open"), 21 | Input("open-fs", "n_clicks"), 22 | State("modal-fs", "is_open"), 23 | ) 24 | def toggle_modal(n, is_open): 25 | if n: 26 | return not is_open 27 | return is_open 28 | -------------------------------------------------------------------------------- /docs/components_page/components/button/outline.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | buttons = html.Div( 5 | [ 6 | dbc.Button("Primary", outline=True, color="primary", className="me-1"), 7 | dbc.Button("Secondary", outline=True, color="secondary", className="me-1"), 8 | dbc.Button("Success", outline=True, color="success", className="me-1"), 9 | dbc.Button("Warning", outline=True, color="warning", className="me-1"), 10 | dbc.Button("Danger", outline=True, color="danger", className="me-1"), 11 | dbc.Button("Info", outline=True, color="info", className="me-1"), 12 | dbc.Button("Light", outline=True, color="light", className="me-1"), 13 | dbc.Button("Dark", outline=True, color="dark"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /src/components/modal/__tests__/ModalFooter.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import ModalFooter from '../ModalFooter'; 9 | 10 | describe('ModalFooter', () => { 11 | test('renders a div with class "modal-footer"', () => { 12 | const modalFooter = render(); 13 | 14 | expect(modalFooter.container.querySelector('div.modal-footer')).not.toBe( 15 | null 16 | ); 17 | }); 18 | 19 | test('renders its content', () => { 20 | const modalFooter = render( 21 | Some modal footer content 22 | ); 23 | 24 | expect(modalFooter.container).toHaveTextContent( 25 | 'Some modal footer content' 26 | ); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/components/modal/__tests__/ModalHeader.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import ModalHeader from '../ModalHeader'; 9 | 10 | describe('ModalHeader', () => { 11 | test('renders a div with class "modal-header"', () => { 12 | const modalHeader = render(); 13 | 14 | expect(modalHeader.container.querySelector('div.modal-header')).not.toBe( 15 | null 16 | ); 17 | }); 18 | 19 | test('renders its content', () => { 20 | const modalHeader = render( 21 | Some modal header content 22 | ); 23 | 24 | expect(modalHeader.container).toHaveTextContent( 25 | 'Some modal header content' 26 | ); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /docs/components_page/components/fade.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fade 3 | lead: Toggle the visibility of content in your apps with a fade animation using the `Fade` component. 4 | --- 5 | 6 | ## Examples 7 | 8 | The `Fade` component can be used to show and hide content in your apps. When the visibility is toggled, the content will fade in / out. Simply set `is_in=True` to show the content, and `is_in=False` to hide it again. The simple example below uses a button click to toggle in the `is_in` prop. 9 | 10 | {{example:components/fade/fade.py:fade}} 11 | 12 | ## Modifying the transition 13 | 14 | You can adjust the transition by modifying the `transition` CSS property using inline styles or by linking a custom stylesheet. 15 | 16 | {{example:components/fade/transition.py:fade}} 17 | 18 | {{apidoc:src/components/Fade.js}} 19 | -------------------------------------------------------------------------------- /docs/components_page/components/jumbotron.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Jumbotron 3 | lead: Lightweight styling for showcasing key content and messages. 4 | --- 5 | 6 | ## Examples 7 | 8 | The Jumbotron component was removed in Bootstrap 5, so there is no longer a dedicated `Jumbotron` component in _dash-bootstrap-components_ either. However, thanks to Bootstrap's flexible utility classes, it is easy to recreate a jumbotron-like layout yourself. Here's a simple example 9 | 10 | {{example:components/jumbotron/simple.py:jumbotron}} 11 | 12 | ### Styling the "Jumbotron" 13 | 14 | There are [many utility classes](https://getbootstrap.com/docs/5.0/utilities/spacing/) available in Bootstrap. By combining them you can easily customise the look and feel of your app. 15 | 16 | {{example:components/jumbotron/custom.py:jumbotron}} 17 | -------------------------------------------------------------------------------- /docs/components_page/components/progress/interval.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, dcc, html 3 | 4 | progress = html.Div( 5 | [ 6 | dcc.Interval(id="progress-interval", n_intervals=0, interval=500), 7 | dbc.Progress(id="progress"), 8 | ] 9 | ) 10 | 11 | 12 | @app.callback( 13 | [Output("progress", "value"), Output("progress", "label")], 14 | [Input("progress-interval", "n_intervals")], 15 | ) 16 | def update_progress(n): 17 | # check progress of some background process, in this example we'll just 18 | # use n_intervals constrained to be in 0-100 19 | progress = min(n % 110, 100) 20 | # only add text after 5% progress to ensure text isn't squashed too much 21 | return progress, f"{progress} %" if progress >= 5 else "" 22 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/offcanvas.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | COOKIE = ( 7 | "https://todaysmama.com/.image/t_share/MTU5OTEwMzkyMDIyMTE1NzAz/cookie-monster.png" # noqa 8 | ) 9 | offcanvas = html.Div( 10 | [ 11 | make_subheading("Offcanvas", "offcanvas"), 12 | html.P( 13 | [ 14 | dbc.Button("Show the cookie monster", id="offcanvas-button"), 15 | dbc.Offcanvas( 16 | html.Img(src=COOKIE, style={"width": "100%"}), 17 | title="Cookies!", 18 | id="offcanvas", 19 | is_open=False, 20 | ), 21 | ] 22 | ), 23 | ], 24 | className="mb-4", 25 | ) 26 | -------------------------------------------------------------------------------- /docs/components_page/components/breadcrumb.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Breadcrumb 3 | lead: Indicate the current page’s location within a navigational hierarchy that automatically adds separators via CSS. 4 | --- 5 | 6 | ## Examples 7 | 8 | You can create breadcrumbs using the `Breadcrumb` component. Items are specified with the `items` prop. You must specify a `label` for each item, and can optionally specify: 9 | - `href` to add a link; 10 | - `external_link` to determine whether the link should be treated as a Dash style link or whether it should reload the page; and, 11 | - `active` to determine whether the item has the "active" style applied to indicate that it corresponds to the current location. 12 | 13 | {{example:components/breadcrumb/simple.py:breadcrumb}} 14 | 15 | {{apidoc:src/components/breadcrumb/Breadcrumb.js}} 16 | -------------------------------------------------------------------------------- /docs/components_page/components/card/image.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | top_card = dbc.Card( 5 | [ 6 | dbc.CardImg(src="/static/images/placeholder286x180.png", top=True), 7 | dbc.CardBody( 8 | html.P("This card has an image at the top", className="card-text") 9 | ), 10 | ], 11 | style={"width": "18rem"}, 12 | ) 13 | 14 | bottom_card = dbc.Card( 15 | [ 16 | dbc.CardBody(html.P("This has a bottom image", className="card-text")), 17 | dbc.CardImg(src="/static/images/placeholder286x180.png", bottom=True), 18 | ], 19 | style={"width": "18rem"}, 20 | ) 21 | 22 | cards = dbc.Row( 23 | [ 24 | dbc.Col(top_card, width="auto"), 25 | dbc.Col(bottom_card, width="auto"), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/breakpoints.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | row = html.Div( 5 | [ 6 | dbc.Row( 7 | [ 8 | dbc.Col(html.Div("One of three columns"), md=4), 9 | dbc.Col(html.Div("One of three columns"), md=4), 10 | dbc.Col(html.Div("One of three columns"), md=4), 11 | ] 12 | ), 13 | dbc.Row( 14 | [ 15 | dbc.Col(html.Div("One of four columns"), width=6, lg=3), 16 | dbc.Col(html.Div("One of four columns"), width=6, lg=3), 17 | dbc.Col(html.Div("One of four columns"), width=6, lg=3), 18 | dbc.Col(html.Div("One of four columns"), width=6, lg=3), 19 | ] 20 | ), 21 | ] 22 | ) 23 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/tooltip.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | tooltip = html.Div( 7 | [ 8 | make_subheading("Tooltip", "tooltip"), 9 | html.P( 10 | [ 11 | "I wonder what ", 12 | html.Span( 13 | "floccinaucinihilipilification", 14 | id="tooltip-target", 15 | style={"textDecoration": "underline", "cursor": "pointer"}, 16 | ), 17 | " means?", 18 | ] 19 | ), 20 | dbc.Tooltip( 21 | "Noun: rare, " "the action or habit of estimating something as worthless.", 22 | target="tooltip-target", 23 | ), 24 | ], 25 | className="mb-4", 26 | ) 27 | -------------------------------------------------------------------------------- /src/components/popover/__tests__/PopoverHeader.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import PopoverHeader from '../PopoverHeader'; 9 | 10 | describe('PopoverHeader', () => { 11 | test('renders an element with class "popover-header"', () => { 12 | const popoverHeader = render(); 13 | 14 | expect(popoverHeader.container.querySelector('.popover-header')).not.toBe( 15 | null 16 | ); 17 | }); 18 | 19 | test('renders its content', () => { 20 | const popoverHeader = render( 21 | Some popover header content 22 | ); 23 | 24 | expect(popoverHeader.container).toHaveTextContent( 25 | 'Some popover header content' 26 | ); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /tests/test_tooltip.py: -------------------------------------------------------------------------------- 1 | from dash import Dash, html 2 | from dash_bootstrap_components import Tooltip, themes 3 | from selenium.webdriver.common.action_chains import ActionChains 4 | 5 | 6 | def test_dbtt001_tooltip_content(dash_duo): 7 | app = Dash(external_stylesheets=[themes.BOOTSTRAP]) 8 | 9 | app.layout = html.Div( 10 | [ 11 | Tooltip("Test content", id="tooltip", target="tooltip-target"), 12 | html.Div("Target", id="tooltip-target"), 13 | ], 14 | className="container p-5", 15 | ) 16 | 17 | dash_duo.start_server(app) 18 | 19 | hover = ActionChains(dash_duo.driver).move_to_element( 20 | dash_duo.wait_for_element_by_id("tooltip-target") 21 | ) 22 | hover.perform() 23 | dash_duo.wait_for_text_to_equal(".tooltip-inner", "Test content", timeout=4) 24 | -------------------------------------------------------------------------------- /docs/components_page/components/input/colorpicker.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | colorpicker = html.Div( 5 | [ 6 | dbc.Label(["Select a ", html.Span("color", id="color")]), 7 | dbc.Input( 8 | type="color", 9 | id="colorpicker", 10 | value="#000000", 11 | style={"width": 75, "height": 50}, 12 | ), 13 | ] 14 | ) 15 | 16 | app.clientside_callback( 17 | """ 18 | function(color) { 19 | return {"color": color} 20 | } 21 | """, 22 | Output("color", "style"), 23 | Input("colorpicker", "value"), 24 | ) 25 | 26 | 27 | # Regular Dash callback 28 | # @app.callback(Output("color", "style"), Input("colorpicker", "value")) 29 | # def update_text(color): 30 | # return {"color": color} 31 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/progress.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | progress = html.Div( 7 | [ 8 | make_subheading("Progress", "progress"), 9 | dbc.Progress(label="25%", value=25), 10 | dbc.Progress(value=50, striped=True, className="my-2"), 11 | dbc.Progress( 12 | value=50, 13 | striped=True, 14 | animated=True, 15 | className="my-2", 16 | ), 17 | dbc.Progress( 18 | [ 19 | dbc.Progress(value=20, color="success", bar=True), 20 | dbc.Progress(value=30, color="warning", bar=True), 21 | dbc.Progress(value=20, color="danger", bar=True), 22 | ] 23 | ), 24 | ], 25 | className="mb-4", 26 | ) 27 | -------------------------------------------------------------------------------- /src/components/card/__tests__/CardImgOverlay.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import CardImgOverlay from '../CardImgOverlay'; 9 | 10 | describe('CardImgOverlay', () => { 11 | test('renders a div with class "card-img-overlay"', () => { 12 | const cardImgOverlay = render(); 13 | 14 | expect( 15 | cardImgOverlay.container.querySelector('div.card-img-overlay') 16 | ).not.toBe(null); 17 | }); 18 | 19 | test('renders its content', () => { 20 | const cardImgOverlay = render( 21 | Some card image overlay content 22 | ); 23 | 24 | expect(cardImgOverlay.container).toHaveTextContent( 25 | 'Some card image overlay content' 26 | ); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /docs/components_page/components/card/image_overlay.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | card = dbc.Card( 5 | [ 6 | dbc.CardImg( 7 | src="/static/images/placeholder286x180.png", 8 | top=True, 9 | style={"opacity": 0.3}, 10 | ), 11 | dbc.CardImgOverlay( 12 | dbc.CardBody( 13 | [ 14 | html.H4("Card title", className="card-title"), 15 | html.P( 16 | "An example of using an image in the background of " "a card.", 17 | className="card-text", 18 | ), 19 | dbc.Button("Go somewhere", color="primary"), 20 | ], 21 | ), 22 | ), 23 | ], 24 | style={"width": "18rem"}, 25 | ) 26 | -------------------------------------------------------------------------------- /docs/components_page/components/collapse/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | collapse = html.Div( 5 | [ 6 | dbc.Button( 7 | "Open collapse", 8 | id="collapse-button", 9 | className="mb-3", 10 | color="primary", 11 | n_clicks=0, 12 | ), 13 | dbc.Collapse( 14 | dbc.Card(dbc.CardBody("This content is hidden in the collapse")), 15 | id="collapse", 16 | is_open=False, 17 | ), 18 | ] 19 | ) 20 | 21 | 22 | @app.callback( 23 | Output("collapse", "is_open"), 24 | [Input("collapse-button", "n_clicks")], 25 | [State("collapse", "is_open")], 26 | ) 27 | def toggle_collapse(n, is_open): 28 | if n: 29 | return not is_open 30 | return is_open 31 | -------------------------------------------------------------------------------- /docs/templates/partials/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/components/input/__tests__/InputGroupText.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import InputGroupText from '../InputGroupText'; 9 | 10 | describe('InputGroupAddon', () => { 11 | test('renders a span with class "input-group-text"', () => { 12 | const inputGroupText = render(); 13 | expect( 14 | inputGroupText.container.querySelector('span.input-group-text') 15 | ).not.toBe(null); 16 | }); 17 | 18 | test('renders its content', () => { 19 | const { 20 | container: {firstChild: inputGroupText} 21 | } = render(Addon); 22 | 23 | expect(inputGroupText).toHaveTextContent('Addon'); 24 | expect(inputGroupText).toHaveClass('input-group-text'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/links.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | list_group = html.Div( 5 | [ 6 | dbc.ListGroup( 7 | [ 8 | dbc.ListGroupItem("Internal link", href="/l/components/list_group"), 9 | dbc.ListGroupItem("External link", href="https://google.com"), 10 | dbc.ListGroupItem( 11 | "Disabled link", href="https://google.com", disabled=True 12 | ), 13 | dbc.ListGroupItem("Button", id="button-item", n_clicks=0, action=True), 14 | ] 15 | ), 16 | html.P(id="counter"), 17 | ] 18 | ) 19 | 20 | 21 | @app.callback(Output("counter", "children"), [Input("button-item", "n_clicks")]) 22 | def count_clicks(n): 23 | return f"Button clicked {n} times" 24 | -------------------------------------------------------------------------------- /docs/components_page/components/tabs/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | tab1_content = dbc.Card( 5 | dbc.CardBody( 6 | [ 7 | html.P("This is tab 1!", className="card-text"), 8 | dbc.Button("Click here", color="success"), 9 | ] 10 | ), 11 | className="mt-3", 12 | ) 13 | 14 | tab2_content = dbc.Card( 15 | dbc.CardBody( 16 | [ 17 | html.P("This is tab 2!", className="card-text"), 18 | dbc.Button("Don't click here", color="danger"), 19 | ] 20 | ), 21 | className="mt-3", 22 | ) 23 | 24 | 25 | tabs = dbc.Tabs( 26 | [ 27 | dbc.Tab(tab1_content, label="Tab 1"), 28 | dbc.Tab(tab2_content, label="Tab 2"), 29 | dbc.Tab("This tab's content is never seen", label="Tab 3", disabled=True), 30 | ] 31 | ) 32 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/modal.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | COOKIE = ( 7 | "https://todaysmama.com/.image/t_share/MTU5OTEwMzkyMDIyMTE1NzAz/cookie-monster.png" # noqa 8 | ) 9 | modal = html.Div( 10 | [ 11 | make_subheading("Modal", "modal"), 12 | html.P( 13 | [ 14 | dbc.Button("Show the cookie monster", id="modal-button"), 15 | dbc.Modal( 16 | [ 17 | dbc.ModalHeader("Cookies!"), 18 | dbc.ModalBody(html.Img(src=COOKIE, style={"width": "100%"})), 19 | ], 20 | id="modal", 21 | is_open=False, 22 | ), 23 | ] 24 | ), 25 | ], 26 | className="mb-4", 27 | ) 28 | -------------------------------------------------------------------------------- /docs/components_page/components/fade/fade.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | fade = html.Div( 5 | [ 6 | dbc.Button("Toggle fade", id="fade-button", className="mb-3", n_clicks=0), 7 | dbc.Fade( 8 | dbc.Card( 9 | dbc.CardBody( 10 | html.P("This content fades in and out", className="card-text") 11 | ) 12 | ), 13 | id="fade", 14 | is_in=False, 15 | appear=False, 16 | ), 17 | ] 18 | ) 19 | 20 | 21 | @app.callback( 22 | Output("fade", "is_in"), 23 | [Input("fade-button", "n_clicks")], 24 | [State("fade", "is_in")], 25 | ) 26 | def toggle_fade(n, is_in): 27 | if not n: 28 | # Button has never been clicked 29 | return False 30 | return not is_in 31 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/accordion.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | accordion = html.Div( 7 | [ 8 | make_subheading("Accordion", "accordion"), 9 | dbc.Accordion( 10 | [ 11 | dbc.AccordionItem( 12 | "This is the content of the first section", 13 | title="Item 1", 14 | ), 15 | dbc.AccordionItem( 16 | "This is the content of the second section", 17 | title="Item 2", 18 | ), 19 | dbc.AccordionItem( 20 | "This is the content of the third section", 21 | title="Item 3", 22 | ), 23 | ], 24 | ), 25 | ], 26 | className="mb-4", 27 | ) 28 | -------------------------------------------------------------------------------- /docs/components_page/components/badge/pills.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | badges = html.Span( 5 | [ 6 | dbc.Badge("Primary", pill=True, color="primary", className="me-1"), 7 | dbc.Badge("Secondary", pill=True, color="secondary", className="me-1"), 8 | dbc.Badge("Success", pill=True, color="success", className="me-1"), 9 | dbc.Badge("Warning", pill=True, color="warning", className="me-1"), 10 | dbc.Badge("Danger", pill=True, color="danger", className="me-1"), 11 | dbc.Badge("Info", pill=True, color="info", className="me-1"), 12 | dbc.Badge( 13 | "Light", 14 | pill=True, 15 | color="light", 16 | text_color="dark", 17 | className="me-1", 18 | ), 19 | dbc.Badge("Dark", pill=True, color="dark"), 20 | ] 21 | ) 22 | -------------------------------------------------------------------------------- /docs/components_page/components/offcanvas/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | offcanvas = html.Div( 5 | [ 6 | dbc.Button("Open Offcanvas", id="open-offcanvas", n_clicks=0), 7 | dbc.Offcanvas( 8 | html.P( 9 | "This is the content of the Offcanvas. " 10 | "Close it by clicking on the close button, or " 11 | "the backdrop." 12 | ), 13 | id="offcanvas", 14 | title="Title", 15 | is_open=False, 16 | ), 17 | ] 18 | ) 19 | 20 | 21 | @app.callback( 22 | Output("offcanvas", "is_open"), 23 | Input("open-offcanvas", "n_clicks"), 24 | [State("offcanvas", "is_open")], 25 | ) 26 | def toggle_offcanvas(n1, is_open): 27 | if n1: 28 | return not is_open 29 | return is_open 30 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/style.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | items = [ 5 | dbc.DropdownMenuItem("Item 1"), 6 | dbc.DropdownMenuItem("Item 2"), 7 | dbc.DropdownMenuItem("Item 3"), 8 | ] 9 | 10 | dropdowns = html.Div( 11 | [ 12 | dbc.DropdownMenu(items, label="Primary", color="primary", className="m-1"), 13 | dbc.DropdownMenu(items, label="Secondary", color="secondary", className="m-1"), 14 | dbc.DropdownMenu(items, label="Success", color="success", className="m-1"), 15 | dbc.DropdownMenu(items, label="Warning", color="warning", className="m-1"), 16 | dbc.DropdownMenu(items, label="Danger", color="danger", className="m-1"), 17 | dbc.DropdownMenu(items, label="Info", color="info", className="m-1"), 18 | ], 19 | style={"display": "flex", "flexWrap": "wrap"}, 20 | ) 21 | -------------------------------------------------------------------------------- /docs/components_page/components/toast/auto_dismiss.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html, no_update 3 | 4 | toast = html.Div( 5 | [ 6 | dbc.Button( 7 | "Open toast", 8 | id="auto-toast-toggle", 9 | color="primary", 10 | className="mb-3", 11 | n_clicks=0, 12 | ), 13 | dbc.Toast( 14 | [html.P("This is the content of the toast", className="mb-0")], 15 | id="auto-toast", 16 | header="This is the header", 17 | icon="primary", 18 | duration=4000, 19 | is_open=False, 20 | ), 21 | ] 22 | ) 23 | 24 | 25 | @app.callback(Output("auto-toast", "is_open"), [Input("auto-toast-toggle", "n_clicks")]) 26 | def open_toast(n): 27 | if n == 0: 28 | return no_update 29 | return True 30 | -------------------------------------------------------------------------------- /docs/components_page/components/jumbotron/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | jumbotron = html.Div( 5 | dbc.Container( 6 | [ 7 | html.H1("Jumbotron", className="display-3"), 8 | html.P( 9 | "Use Containers to create a jumbotron to call attention to " 10 | "featured content or information.", 11 | className="lead", 12 | ), 13 | html.Hr(className="my-2"), 14 | html.P( 15 | "Use utility classes for typography and spacing to suit the " 16 | "larger container." 17 | ), 18 | html.P(dbc.Button("Learn more", color="primary"), className="lead"), 19 | ], 20 | fluid=True, 21 | className="py-3", 22 | ), 23 | className="p-3 bg-body-secondary rounded-3", 24 | ) 25 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/util.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | DBC_DOCS = "https://www.dash-bootstrap-components.com/docs/components/" 5 | 6 | 7 | def make_subheading(label, link): 8 | slug = label.replace(" ", "") 9 | 10 | heading = html.H2( 11 | html.Span( 12 | [ 13 | label, 14 | html.A( 15 | html.I(className="fas fa-book fa-xs ms-2"), 16 | href=f"{DBC_DOCS}{link}", 17 | target="_blank", 18 | id=f"tooltip_target_{slug}", 19 | ), 20 | ], 21 | ), 22 | ) 23 | 24 | return html.Div( 25 | [ 26 | heading, 27 | dbc.Tooltip(f"See {label} documentation", target=f"tooltip_target_{slug}"), 28 | ], 29 | className="mt-3", 30 | ) 31 | -------------------------------------------------------------------------------- /docs/components_page/components/form/grid.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | form = dbc.Row( 4 | [ 5 | dbc.Col( 6 | [ 7 | dbc.Label("Email", html_for="example-email-grid"), 8 | dbc.Input( 9 | type="email", 10 | id="example-email-grid", 11 | placeholder="Enter email", 12 | ), 13 | ], 14 | width=6, 15 | ), 16 | dbc.Col( 17 | [ 18 | dbc.Label("Password", html_for="example-password-grid"), 19 | dbc.Input( 20 | type="password", 21 | id="example-password-grid", 22 | placeholder="Enter password", 23 | ), 24 | ], 25 | width=6, 26 | ), 27 | ], 28 | className="g-3", 29 | ) 30 | -------------------------------------------------------------------------------- /docs/components_page/components/form/feedback.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | email_input = html.Div( 5 | [ 6 | dbc.Label("Email"), 7 | dbc.Input(id="email-input", type="email", value=""), 8 | dbc.FormText("We only accept gmail..."), 9 | dbc.FormFeedback("That looks like a gmail address :-)", type="valid"), 10 | dbc.FormFeedback( 11 | "Sorry, we only accept gmail for some reason...", 12 | type="invalid", 13 | ), 14 | ] 15 | ) 16 | 17 | 18 | # --- Callbacks --- # 19 | @app.callback( 20 | [Output("email-input", "valid"), Output("email-input", "invalid")], 21 | [Input("email-input", "value")], 22 | ) 23 | def check_validity(text): 24 | if text: 25 | is_gmail = text.endswith("@gmail.com") 26 | return is_gmail, not is_gmail 27 | return False, False 28 | -------------------------------------------------------------------------------- /docs/components_page/components/nav/navlink.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | nav = html.Div( 5 | [ 6 | dbc.Nav( 7 | [ 8 | dbc.NavLink("Internal link", href="/l/components/nav"), 9 | dbc.NavLink("External link", href="https://github.com"), 10 | dbc.NavLink( 11 | "External relative", 12 | href="/l/components/nav", 13 | external_link=True, 14 | ), 15 | dbc.NavLink("Button", id="button-link", n_clicks=0), 16 | ] 17 | ), 18 | html.Br(), 19 | html.P(id="button-clicks"), 20 | ] 21 | ) 22 | 23 | 24 | @app.callback(Output("button-clicks", "children"), [Input("button-link", "n_clicks")]) 25 | def show_clicks(n): 26 | return "Button clicked {} times".format(n) 27 | -------------------------------------------------------------------------------- /docs/components_page/components/accordion/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | accordion = html.Div( 5 | dbc.Accordion( 6 | [ 7 | dbc.AccordionItem( 8 | [ 9 | html.P("This is the content of the first section"), 10 | dbc.Button("Click here"), 11 | ], 12 | title="Item 1", 13 | ), 14 | dbc.AccordionItem( 15 | [ 16 | html.P("This is the content of the second section"), 17 | dbc.Button("Don't click me!", color="danger"), 18 | ], 19 | title="Item 2", 20 | ), 21 | dbc.AccordionItem( 22 | "This is the content of the third section", 23 | title="Item 3", 24 | ), 25 | ], 26 | ) 27 | ) 28 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/horizontal.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | row_content = [ 5 | dbc.Col(html.Div("One of two columns"), width=4), 6 | dbc.Col(html.Div("One of two columns"), width=4), 7 | ] 8 | 9 | row = html.Div( 10 | [ 11 | dbc.Row( 12 | row_content, 13 | justify="start", 14 | ), 15 | dbc.Row( 16 | row_content, 17 | justify="center", 18 | ), 19 | dbc.Row( 20 | row_content, 21 | justify="end", 22 | ), 23 | dbc.Row( 24 | row_content, 25 | justify="between", 26 | ), 27 | dbc.Row( 28 | row_content, 29 | justify="around", 30 | ), 31 | dbc.Row( 32 | row_content, 33 | justify="evenly", 34 | ), 35 | ] 36 | ) 37 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/stack_spacers.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | demo_div = "bg-primary-subtle border border-primary-subtle p-2" 5 | 6 | stack = html.Div( 7 | [ 8 | dbc.Stack( 9 | [ 10 | html.Div("Start"), 11 | html.Div( 12 | "Middle (ms-auto)", 13 | className="ms-auto", 14 | ), 15 | html.Div("End"), 16 | ], 17 | direction="horizontal", 18 | gap=3, 19 | ), 20 | html.Hr(), 21 | dbc.Stack( 22 | [ 23 | html.Div("Start"), 24 | html.Div("Middle (mx-auto)", className="mx-auto"), 25 | html.Div("End"), 26 | ], 27 | direction="horizontal", 28 | gap=3, 29 | ), 30 | ] 31 | ) 32 | -------------------------------------------------------------------------------- /docs/components_page/components/button_group/radios.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | button_group = html.Div( 5 | [ 6 | dbc.RadioItems( 7 | id="radios", 8 | className="btn-group", 9 | inputClassName="btn-check", 10 | labelClassName="btn btn-outline-primary", 11 | labelCheckedClassName="active", 12 | options=[ 13 | {"label": "Option 1", "value": 1}, 14 | {"label": "Option 2", "value": 2}, 15 | {"label": "Option 3", "value": 3}, 16 | ], 17 | value=1, 18 | ), 19 | html.Div(id="output"), 20 | ], 21 | className="radio-group", 22 | ) 23 | 24 | 25 | @app.callback(Output("output", "children"), [Input("radios", "value")]) 26 | def display_value(value): 27 | return f"Selected value: {value}" 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | Before opening: 2 | 3 | - [Search for duplicate or closed issues](https://github.com/dbc-team/dash-bootstrap-components/issues?utf8=%E2%9C%93&q=is%3Aissue) 4 | - Read the [contributing guidelines](https://github.com/dbc-team/dash-bootstrap-components/blob/main/.github/CONTRIBUTING.md) 5 | 6 | Please fill out the below information as much as possible. 7 | 8 | - dash version: `#x.x.x` 9 | - dash-bootstrap-components version: `#x.x.x` 10 | - components affected by bug: 11 | 12 | ### What is happening? 13 | 14 | 15 | 16 | ### What should be happening? 17 | 18 | 19 | 20 | ### Code 21 | 22 | 25 | 26 | ```python 27 | # your code here 28 | ``` 29 | 30 | ### Error messages 31 | 32 | ```bash 33 | paste any error messages here 34 | ``` 35 | -------------------------------------------------------------------------------- /docs/components_page/components/toast/icon_dismiss.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html, no_update 3 | 4 | toast = html.Div( 5 | [ 6 | dbc.Button( 7 | "Open toast", 8 | id="simple-toast-toggle", 9 | color="primary", 10 | className="mb-3", 11 | n_clicks=0, 12 | ), 13 | dbc.Toast( 14 | [html.P("This is the content of the toast", className="mb-0")], 15 | id="simple-toast", 16 | header="This is the header", 17 | icon="primary", 18 | dismissable=True, 19 | is_open=False, 20 | ), 21 | ] 22 | ) 23 | 24 | 25 | @app.callback( 26 | Output("simple-toast", "is_open"), 27 | [Input("simple-toast-toggle", "n_clicks")], 28 | ) 29 | def open_toast(n): 30 | if n == 0: 31 | return no_update 32 | return True 33 | -------------------------------------------------------------------------------- /docs/components_page/components/tooltip/tooltip_callback.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | tooltip = html.Div( 5 | [ 6 | dbc.Button( 7 | "Toggle", 8 | id="toggle", 9 | color="success", 10 | className="me-4", 11 | n_clicks=0, 12 | ), 13 | dbc.Button("Target", id="target", color="danger", n_clicks=0), 14 | dbc.Tooltip( 15 | "This is a tooltip", 16 | id="tooltip", 17 | is_open=False, 18 | target="target", 19 | trigger=None, 20 | ), 21 | ] 22 | ) 23 | 24 | 25 | @app.callback( 26 | Output("tooltip", "is_open"), 27 | [Input("toggle", "n_clicks")], 28 | [State("tooltip", "is_open")], 29 | ) 30 | def toggle_tooltip(n, is_open): 31 | if n: 32 | return not is_open 33 | return is_open 34 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/nav.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | nav_items = [ 7 | dbc.NavItem(dbc.NavLink("Active", active=True, href="#")), 8 | dbc.NavItem(dbc.NavLink("A link", href="#")), 9 | dbc.NavItem(dbc.NavLink("Another link", href="#")), 10 | dbc.NavItem(dbc.NavLink("Disabled", disabled=True, href="#")), 11 | dbc.DropdownMenu( 12 | [dbc.DropdownMenuItem("Item 1"), dbc.DropdownMenuItem("Item 2")], 13 | label="Dropdown", 14 | nav=True, 15 | ), 16 | ] 17 | 18 | nav1 = dbc.Col( 19 | dbc.Nav( 20 | nav_items, 21 | ), 22 | md=6, 23 | xs=12, 24 | ) 25 | 26 | nav2 = dbc.Col( 27 | dbc.Nav(nav_items, pills=True), 28 | md=6, 29 | xs=12, 30 | ) 31 | 32 | nav = html.Div( 33 | [make_subheading("Nav", "nav"), dbc.Row([nav1, nav2])], 34 | className="mb-4", 35 | ) 36 | -------------------------------------------------------------------------------- /docs/components_page/components/offcanvas/scrollable.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | offcanvas = html.Div( 5 | [ 6 | dbc.Button( 7 | "Open scrollable offcanvas", 8 | id="open-offcanvas-scrollable", 9 | n_clicks=0, 10 | ), 11 | dbc.Offcanvas( 12 | html.P("The contents on the main page are now scrollable."), 13 | id="offcanvas-scrollable", 14 | scrollable=True, 15 | title="Scrollable Offcanvas", 16 | is_open=False, 17 | ), 18 | ] 19 | ) 20 | 21 | 22 | @app.callback( 23 | Output("offcanvas-scrollable", "is_open"), 24 | Input("open-offcanvas-scrollable", "n_clicks"), 25 | State("offcanvas-scrollable", "is_open"), 26 | ) 27 | def toggle_offcanvas_scrollable(n1, is_open): 28 | if n1: 29 | return not is_open 30 | return is_open 31 | -------------------------------------------------------------------------------- /docs/components_page/components/modal/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | modal = html.Div( 5 | [ 6 | dbc.Button("Open modal", id="open", n_clicks=0), 7 | dbc.Modal( 8 | [ 9 | dbc.ModalHeader(dbc.ModalTitle("Header")), 10 | dbc.ModalBody("This is the content of the modal"), 11 | dbc.ModalFooter( 12 | dbc.Button("Close", id="close", className="ms-auto", n_clicks=0) 13 | ), 14 | ], 15 | id="modal", 16 | is_open=False, 17 | ), 18 | ] 19 | ) 20 | 21 | 22 | @app.callback( 23 | Output("modal", "is_open"), 24 | [Input("open", "n_clicks"), Input("close", "n_clicks")], 25 | [State("modal", "is_open")], 26 | ) 27 | def toggle_modal(n1, n2, is_open): 28 | if n1 or n2: 29 | return not is_open 30 | return is_open 31 | -------------------------------------------------------------------------------- /docs/components_page/components/popover/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | popovers = html.Div( 5 | [ 6 | # First example - using dbc.PopoverBody 7 | dbc.Button( 8 | "popover-target", 9 | id="popover-target", 10 | className="me-1", 11 | ), 12 | dbc.Popover( 13 | dbc.PopoverBody("My `target` is `popover-target`."), 14 | target="popover-target", 15 | trigger="click", 16 | ), 17 | # Second example - using body=True 18 | dbc.Button( 19 | "popover-alt-target", 20 | id="popover-alt-target", 21 | className="me-1", 22 | ), 23 | dbc.Popover( 24 | "My `target` is `popover-alt-target`.", 25 | body=True, 26 | target="popover-alt-target", 27 | trigger="click", 28 | ), 29 | ] 30 | ) 31 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/fade.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | fade = html.Div( 7 | [ 8 | make_subheading("Fade", "fade"), 9 | html.Div( 10 | [ 11 | dbc.Button( 12 | "Toggle fade", 13 | id="fade-button", 14 | style={"marginBottom": "1rem"}, 15 | ), 16 | dbc.Fade( 17 | dbc.Card( 18 | dbc.CardBody( 19 | html.P( 20 | "This content fades in and out", 21 | className="card-text", 22 | ) 23 | ) 24 | ), 25 | id="fade", 26 | is_in=True, 27 | ), 28 | ] 29 | ), 30 | ], 31 | ) 32 | -------------------------------------------------------------------------------- /docs/templates/example.html: -------------------------------------------------------------------------------- 1 | {% from "macros/example-navbar.html" import example_navbar %} 2 | {% extends "base.html" %} 3 | {% block header %}{{ example_navbar() }}{% endblock %} 4 | {% block body %} 5 |
6 | {% block size_warning %}{% endblock %} 7 |
10 | {% block content %}{% endblock %} 11 |
12 |
13 |

Source Code

14 | 19 |

20 | This code is available 21 | in the examples directory of our GitHub 22 | repository. 23 |

24 |
{% block code %}{% endblock %}
27 |
28 |
29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /docs/components_page/components/card/sizing/grid.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | first_card = dbc.Card( 5 | dbc.CardBody( 6 | [ 7 | html.H5("Card title", className="card-title"), 8 | html.P("This card has some text content, but not much else"), 9 | dbc.Button("Go somewhere", color="primary"), 10 | ] 11 | ) 12 | ) 13 | 14 | 15 | second_card = dbc.Card( 16 | dbc.CardBody( 17 | [ 18 | html.H5("Card title", className="card-title"), 19 | html.P( 20 | "This card also has some text content and not much else, but " 21 | "it is twice as wide as the first card." 22 | ), 23 | dbc.Button("Go somewhere", color="primary"), 24 | ] 25 | ) 26 | ) 27 | 28 | 29 | cards = dbc.Row( 30 | [ 31 | dbc.Col(first_card, width=4), 32 | dbc.Col(second_card, width=8), 33 | ] 34 | ) 35 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/direction.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | 3 | items = [ 4 | dbc.DropdownMenuItem("First"), 5 | dbc.DropdownMenuItem(divider=True), 6 | dbc.DropdownMenuItem("Second"), 7 | ] 8 | 9 | dropdown = dbc.Row( 10 | [ 11 | dbc.Col( 12 | dbc.DropdownMenu( 13 | label="Dropdown (default)", children=items, direction="down" 14 | ), 15 | width="auto", 16 | ), 17 | dbc.Col( 18 | dbc.DropdownMenu(label="Dropstart", children=items, direction="start"), 19 | width="auto", 20 | ), 21 | dbc.Col( 22 | dbc.DropdownMenu(label="Dropend", children=items, direction="end"), 23 | width="auto", 24 | ), 25 | dbc.Col( 26 | dbc.DropdownMenu(label="Dropup", children=items, direction="up"), 27 | width="auto", 28 | ), 29 | ], 30 | justify="between", 31 | ) 32 | -------------------------------------------------------------------------------- /docs/components_page/components/form/simple.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | email_input = html.Div( 5 | [ 6 | dbc.Label("Email", html_for="example-email"), 7 | dbc.Input(type="email", id="example-email", placeholder="Enter email"), 8 | dbc.FormText( 9 | "Are you on email? You simply have to be these days", 10 | color="secondary", 11 | ), 12 | ], 13 | className="mb-3", 14 | ) 15 | 16 | password_input = html.Div( 17 | [ 18 | dbc.Label("Password", html_for="example-password"), 19 | dbc.Input( 20 | type="password", 21 | id="example-password", 22 | placeholder="Enter password", 23 | ), 24 | dbc.FormText( 25 | "A password stops mean people taking your stuff", color="secondary" 26 | ), 27 | ], 28 | className="mb-3", 29 | ) 30 | 31 | form = dbc.Form([email_input, password_input]) 32 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/order_offset.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | row = html.Div( 5 | [ 6 | dbc.Row( 7 | dbc.Col( 8 | html.Div("A single, half-width column"), 9 | width={"size": 6, "offset": 3}, 10 | ) 11 | ), 12 | dbc.Row( 13 | [ 14 | dbc.Col( 15 | html.Div("The last of three columns"), 16 | width={"size": 3, "order": "last", "offset": 1}, 17 | ), 18 | dbc.Col( 19 | html.Div("The first of three columns"), 20 | width={"size": 3, "order": 1, "offset": 2}, 21 | ), 22 | dbc.Col( 23 | html.Div("The second of three columns"), 24 | width={"size": 3, "order": 5}, 25 | ), 26 | ] 27 | ), 28 | ] 29 | ) 30 | -------------------------------------------------------------------------------- /docs/components_page/components/popover/styling.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | popovers = html.Div( 5 | [ 6 | dbc.Button( 7 | "Hidden Arrow", 8 | id="hide-arrow-target", 9 | className="me-1", 10 | n_clicks=0, 11 | ), 12 | dbc.Popover( 13 | "I am a popover without an arrow!", 14 | target="hide-arrow-target", 15 | trigger="legacy", 16 | hide_arrow=True, 17 | body=True, 18 | ), 19 | dbc.Button( 20 | "Offset Popover", 21 | id="offset-target", 22 | n_clicks=0, 23 | ), 24 | dbc.Popover( 25 | "I am a popover that's been offset!", 26 | target="offset-target", 27 | trigger="legacy", 28 | hide_arrow=True, 29 | offset="50,20", 30 | body=True, 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /docs/components_page/components/form/dash_core.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import dcc, html 3 | 4 | dropdown = html.Div( 5 | [ 6 | dbc.Label("Dropdown", html_for="dropdown"), 7 | dcc.Dropdown( 8 | id="dropdown", 9 | options=[ 10 | {"label": "Option 1", "value": 1}, 11 | {"label": "Option 2", "value": 2}, 12 | ], 13 | ), 14 | ], 15 | className="mb-3", 16 | ) 17 | 18 | slider = html.Div( 19 | [ 20 | dbc.Label("Slider", html_for="slider"), 21 | dcc.Slider(id="slider", min=0, max=10, step=0.5, value=3), 22 | ], 23 | className="mb-3", 24 | ) 25 | 26 | range_slider = html.Div( 27 | [ 28 | dbc.Label("RangeSlider", html_for="range-slider"), 29 | dcc.RangeSlider(id="range-slider", min=0, max=10, value=[3, 7]), 30 | ], 31 | className="mb-3", 32 | ) 33 | 34 | form = dbc.Form([dropdown, slider, range_slider]) 35 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/tabs.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | tabs = html.Div( 7 | [ 8 | make_subheading("Tabs", "tabs"), 9 | dbc.Tabs( 10 | [ 11 | dbc.Tab(html.P("This is tab 1", className="py-3"), label="Tab 1"), 12 | dbc.Tab( 13 | dbc.Card( 14 | [ 15 | html.P( 16 | "This tab has a card!", 17 | className="card-text", 18 | ), 19 | dbc.Button("Click here", color="success"), 20 | ], 21 | body=True, 22 | ), 23 | label="Tab 2", 24 | style={"padding": "10px"}, 25 | ), 26 | ] 27 | ), 28 | ], 29 | className="mb-4", 30 | ) 31 | -------------------------------------------------------------------------------- /docs/components_page/components/toast/position.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | toast = html.Div( 5 | [ 6 | dbc.Button( 7 | "Open toast", 8 | id="positioned-toast-toggle", 9 | color="primary", 10 | n_clicks=0, 11 | ), 12 | dbc.Toast( 13 | "This toast is placed in the top right", 14 | id="positioned-toast", 15 | header="Positioned toast", 16 | is_open=False, 17 | dismissable=True, 18 | icon="danger", 19 | # top: 66 positions the toast below the navbar 20 | style={"position": "fixed", "top": 66, "right": 10, "width": 350}, 21 | ), 22 | ] 23 | ) 24 | 25 | 26 | @app.callback( 27 | Output("positioned-toast", "is_open"), 28 | [Input("positioned-toast-toggle", "n_clicks")], 29 | ) 30 | def open_toast(n): 31 | if n: 32 | return True 33 | return False 34 | -------------------------------------------------------------------------------- /docs/components_page/components/input/components_in_labels.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | flights = html.Div([html.I(className="bi bi-airplane pe-1"), "Flights"]) 5 | car = html.Div([html.I(className="bi bi-car-front pe-1"), "Rental Car"]) 6 | hotel = html.Div([html.I(className="bi bi-house pe-1"), "Hotel"]) 7 | 8 | radioitems = html.Div( 9 | [ 10 | dbc.Label("Booking"), 11 | dbc.RadioItems( 12 | options=[ 13 | {"label": flights, "value": 1}, 14 | {"label": car, "value": 2}, 15 | {"label": hotel, "value": 3}, 16 | ], 17 | value=1, 18 | id="radioitems-with-icons", 19 | ), 20 | ] 21 | ) 22 | 23 | checkbox = dbc.Checkbox( 24 | id="checkbox-with-link", 25 | label=html.Div(["I agree to the ", html.A("Terms and Conditions", href="#")]), 26 | value=False, 27 | ) 28 | 29 | components_in_labels = html.Div([radioitems, html.Hr(), checkbox]) 30 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/alert.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | alerts1 = dbc.Col( 7 | [ 8 | dbc.Alert("This is a primary alert", color="primary"), 9 | dbc.Alert("This is a secondary alert", color="secondary"), 10 | dbc.Alert("This is a success alert! Well done!", color="success"), 11 | dbc.Alert("This is a warning alert... be careful...", color="warning"), 12 | ], 13 | md=6, 14 | xs=12, 15 | ) 16 | 17 | alerts2 = dbc.Col( 18 | [ 19 | dbc.Alert("This is a danger alert. Scary!", color="danger"), 20 | dbc.Alert("This is an info alert. Good to know!", color="info"), 21 | dbc.Alert("This is a light alert", color="light"), 22 | dbc.Alert("This is a dark alert", color="dark"), 23 | ], 24 | md=6, 25 | xs=12, 26 | ) 27 | 28 | alerts = html.Div( 29 | [make_subheading("Alert", "alert"), dbc.Row([alerts1, alerts2])], 30 | className="mb-4", 31 | ) 32 | -------------------------------------------------------------------------------- /docs/run.py: -------------------------------------------------------------------------------- 1 | from werkzeug.middleware.dispatcher import DispatcherMiddleware 2 | 3 | from components_page import register_apps as register_component_apps # noqa 4 | from demos import register_apps as register_demo_apps # noqa 5 | from examples import register_apps as register_example_apps # noqa 6 | from markdown_to_html import convert_all_markdown_files # noqa 7 | from server import create_server # noqa 8 | 9 | convert_all_markdown_files() 10 | 11 | server = create_server() 12 | component_routes = register_component_apps() 13 | example_routes = register_example_apps() 14 | demo_routes = register_demo_apps() 15 | routes = {**component_routes, **example_routes, **demo_routes} 16 | application = DispatcherMiddleware( 17 | server, {slug: app.server for slug, app in routes.items()} 18 | ) 19 | 20 | if __name__ == "__main__": 21 | import os 22 | 23 | from werkzeug.serving import run_simple 24 | 25 | os.environ["DBC_DOCS_MODE"] = "dev" 26 | run_simple("localhost", 8888, application, use_reloader=True) 27 | -------------------------------------------------------------------------------- /docs/components_page/components/pagination/callback.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, dcc, html 3 | 4 | pagination = html.Div( 5 | [ 6 | html.Div("Select a page", id="pagination-contents"), 7 | dbc.Pagination(id="pagination", max_value=10), 8 | html.Div("Or set the page dynamically using the slider below"), 9 | dcc.Slider( 10 | id="page-change", 11 | min=1, 12 | max=10, 13 | step=1, 14 | value=1, 15 | marks={i: str(i) for i in range(1, 11)}, 16 | ), 17 | ] 18 | ) 19 | 20 | 21 | @app.callback( 22 | Output("pagination-contents", "children"), 23 | [Input("pagination", "active_page")], 24 | ) 25 | def change_page(page): 26 | if page: 27 | return f"Page selected: {page}" 28 | return "Select a page" 29 | 30 | 31 | @app.callback(Output("pagination", "active_page"), [Input("page-change", "value")]) 32 | def change_active_page(value): 33 | return value 34 | -------------------------------------------------------------------------------- /docs/components_page/components/popover/popover_callback.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | popover = html.Div( 5 | [ 6 | dbc.Button( 7 | "Toggle", 8 | id="toggle", 9 | color="success", 10 | className="me-4", 11 | n_clicks=0, 12 | ), 13 | dbc.Button("Target", id="target", color="danger", n_clicks=0), 14 | dbc.Popover( 15 | [ 16 | dbc.PopoverHeader("Popover header"), 17 | dbc.PopoverBody("And here's some amazing content. Cool!"), 18 | ], 19 | id="popover", 20 | is_open=False, 21 | target="target", 22 | ), 23 | ] 24 | ) 25 | 26 | 27 | @app.callback( 28 | Output("popover", "is_open"), 29 | [Input("toggle", "n_clicks")], 30 | [State("popover", "is_open")], 31 | ) 32 | def toggle_popover(n, is_open): 33 | if n: 34 | return not is_open 35 | return is_open 36 | -------------------------------------------------------------------------------- /docs/components_page/helpers.py: -------------------------------------------------------------------------------- 1 | from dash import dcc, html 2 | 3 | 4 | def HighlightedSource(source): 5 | return html.Div( 6 | dcc.Markdown(f"```python\n{source}\n```"), 7 | className="example-source-container", 8 | ) 9 | 10 | 11 | def ExampleContainer(component, source): 12 | return html.Div( 13 | [ 14 | html.Div(component, className="example"), 15 | HighlightedSource(source), 16 | ], 17 | className="example-container", 18 | ) 19 | 20 | 21 | def load_source_with_environment(source, component_name, environment=None): 22 | """ 23 | Execute a source snippet, injecting the variables specified in environment 24 | 25 | Return the local variable defined by `component_name`. This should be used 26 | for source files that need to register `@app` callbacks. In this case, be 27 | sure to pass app in the environment. 28 | """ 29 | environment = environment or {} 30 | exec(source, environment) 31 | return environment[component_name] 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Tell us about a bug you may have identified in Dash Bootstrap Components 4 | --- 5 | 6 | Before opening: 7 | 8 | - [Search for duplicate or closed issues](https://github.com/dbc-team/dash-bootstrap-components/issues?utf8=%E2%9C%93&q=is%3Aissue) 9 | - Read the [contributing guidelines](https://github.com/dbc-team/dash-bootstrap-components/blob/main/.github/CONTRIBUTING.md) 10 | 11 | Please fill out the below information as much as possible. 12 | 13 | - dash version: `#x.x.x` 14 | - dash-bootstrap-components version: `#x.x.x` 15 | - components affected by bug: 16 | 17 | ### What is happening? 18 | 19 | 20 | 21 | ### What should be happening? 22 | 23 | 24 | 25 | ### Code 26 | 27 | 30 | 31 | ```python 32 | # your code here 33 | ``` 34 | 35 | ### Error messages 36 | 37 | ```bash 38 | paste any error messages here 39 | ``` 40 | -------------------------------------------------------------------------------- /docs/components_page/components/fade/transition.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | fade = html.Div( 5 | [ 6 | dbc.Button( 7 | "Toggle fade", 8 | id="fade-transition-button", 9 | className="mb-3", 10 | n_clicks=0, 11 | ), 12 | dbc.Fade( 13 | dbc.Card( 14 | dbc.CardBody( 15 | html.P("This content fades in and out", className="card-text") 16 | ) 17 | ), 18 | id="fade-transition", 19 | is_in=True, 20 | style={"transition": "opacity 2000ms ease"}, 21 | timeout=2000, 22 | ), 23 | ] 24 | ) 25 | 26 | 27 | @app.callback( 28 | Output("fade-transition", "is_in"), 29 | [Input("fade-transition-button", "n_clicks")], 30 | [State("fade-transition", "is_in")], 31 | ) 32 | def toggle_fade(n, is_in): 33 | if not n: 34 | # Button has never been clicked 35 | return True 36 | return not is_in 37 | -------------------------------------------------------------------------------- /src/components/layout/__tests__/Row.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import Row from '../Row'; 9 | 10 | describe('Row', () => { 11 | test('renders a div with class "row"', () => { 12 | const row = render(); 13 | 14 | expect(row.container.querySelector('div.row')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const row = render(Some row content); 19 | 20 | expect(row.container).toHaveTextContent('Some row content'); 21 | }); 22 | 23 | test('applies additional CSS classes when props are set', () => { 24 | // row align 25 | const { 26 | container: {firstChild: rowAlign} 27 | } = render(); 28 | 29 | expect(rowAlign).toHaveClass('align-items-center'); 30 | 31 | // row justify 32 | const { 33 | container: {firstChild: rowJustify} 34 | } = render(); 35 | 36 | expect(rowJustify).toHaveClass('justify-content-between'); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /docs/components_page/components/carousel/callback.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | carousel = html.Div( 5 | [ 6 | dbc.Carousel( 7 | id="carousel", 8 | items=[ 9 | {"key": "1", "src": "/static/images/slide1.svg"}, 10 | {"key": "2", "src": "/static/images/slide2.svg"}, 11 | {"key": "3", "src": "/static/images/slide3.svg"}, 12 | ], 13 | controls=False, 14 | indicators=False, 15 | interval=None, 16 | ), 17 | dbc.RadioItems( 18 | id="slide-number", 19 | options=[ 20 | {"label": "Slide 1", "value": 0}, 21 | {"label": "Slide 2", "value": 1}, 22 | {"label": "Slide 3", "value": 2}, 23 | ], 24 | value=0, 25 | inline=True, 26 | ), 27 | ] 28 | ) 29 | 30 | 31 | @app.callback( 32 | Output("carousel", "active_index"), 33 | Input("slide-number", "value"), 34 | ) 35 | def select_slide(idx): 36 | return idx 37 | -------------------------------------------------------------------------------- /docs/components_page/components/dropdown/menu_items.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | dropdown = html.Div( 5 | [ 6 | dbc.DropdownMenu( 7 | [ 8 | dbc.DropdownMenuItem("A button", id="dropdown-button", n_clicks=0), 9 | dbc.DropdownMenuItem( 10 | "Internal link", href="/docs/components/dropdown_menu" 11 | ), 12 | dbc.DropdownMenuItem("External Link", href="https://github.com"), 13 | dbc.DropdownMenuItem( 14 | "External relative", 15 | href="/docs/components/dropdown_menu", 16 | external_link=True, 17 | ), 18 | ], 19 | label="Menu", 20 | ), 21 | html.P(id="item-clicks", className="mt-3"), 22 | ] 23 | ) 24 | 25 | 26 | @app.callback(Output("item-clicks", "children"), [Input("dropdown-button", "n_clicks")]) 27 | def count_clicks(n): 28 | if n: 29 | return f"Button clicked {n} times." 30 | return "Button not clicked yet." 31 | -------------------------------------------------------------------------------- /docs/components_page/components/input/selected_styles.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | checklist = html.Div( 5 | [ 6 | dbc.Checklist( 7 | id="checklist-selected-style", 8 | options=[ 9 | {"label": "Option 1", "value": 1}, 10 | {"label": "Option 2", "value": 2}, 11 | {"label": "Option 3", "value": 3}, 12 | ], 13 | label_checked_style={"color": "red"}, 14 | input_checked_style={ 15 | "backgroundColor": "#fa7268", 16 | "borderColor": "#ea6258", 17 | }, 18 | ), 19 | html.Hr(), 20 | dbc.RadioItems( 21 | id="radio-selected-style", 22 | options=[ 23 | {"label": "Option 1", "value": 1}, 24 | {"label": "Option 2", "value": 2}, 25 | {"label": "Option 3", "value": 3}, 26 | ], 27 | labelCheckedClassName="text-success", 28 | inputCheckedClassName="border border-success bg-success", 29 | ), 30 | ] 31 | ) 32 | -------------------------------------------------------------------------------- /src/components/layout/__tests__/Container.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import Container from '../Container'; 9 | 10 | describe('Container', () => { 11 | test('renders a div with class "container"', () => { 12 | const container = render(); 13 | 14 | expect(container.container.querySelector('div.container')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const container = render(Some container content); 19 | 20 | expect(container.container).toHaveTextContent('Some container content'); 21 | }); 22 | 23 | test('renders a fluid container if "fluid" is set', () => { 24 | const { 25 | container: {firstChild: container} 26 | } = render(); 27 | 28 | expect(container).toHaveClass('container-fluid'); 29 | 30 | const { 31 | container: {firstChild: containerMd} 32 | } = render(); 33 | 34 | expect(containerMd).toHaveClass('container-md'); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /docs/components_page/components/collapse.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Collapse 3 | lead: Toggle the visibility of content in your apps using the `Collapse` component. 4 | --- 5 | 6 | ## Examples 7 | 8 | The `Collapse` component can be used to show and hide content in your apps. Simply set `is_open=True` to show the content, and `is_open=False` to hide it. This simple example uses a button click to toggle the `is_open` prop. 9 | 10 | {{example:components/collapse/simple.py:collapse}} 11 | 12 | ## Horizontal collapse 13 | 14 | To change the animation to appear horizontally instead of vertically, set `dimension='width'` instead. When using this animation, you should use dimensions on the objects inside the `Collapse` as below. 15 | 16 | {{example:components/collapse/horizontal.py:collapse}} 17 | 18 | ## Multiple targets 19 | 20 | You can write arbitrarily complex callbacks to control the behaviour of your `Collapse` components. This example has a single button controlling multiple `Collapse` components, as well as multiple buttons sharing control of a single `Collapse` component. 21 | 22 | {{example:components/collapse/multiple.py:collapses}} 23 | 24 | {{apidoc:src/components/Collapse.js}} 25 | -------------------------------------------------------------------------------- /docs/components_page/components/modal/centered.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | modal = html.Div( 5 | [ 6 | dbc.Button("Open", id="open-centered"), 7 | dbc.Modal( 8 | [ 9 | dbc.ModalHeader(dbc.ModalTitle("Header"), close_button=True), 10 | dbc.ModalBody("This modal is vertically centered"), 11 | dbc.ModalFooter( 12 | dbc.Button( 13 | "Close", 14 | id="close-centered", 15 | className="ms-auto", 16 | n_clicks=0, 17 | ) 18 | ), 19 | ], 20 | id="modal-centered", 21 | centered=True, 22 | is_open=False, 23 | ), 24 | ] 25 | ) 26 | 27 | 28 | @app.callback( 29 | Output("modal-centered", "is_open"), 30 | [Input("open-centered", "n_clicks"), Input("close-centered", "n_clicks")], 31 | [State("modal-centered", "is_open")], 32 | ) 33 | def toggle_modal(n1, n2, is_open): 34 | if n1 or n2: 35 | return not is_open 36 | return is_open 37 | -------------------------------------------------------------------------------- /docs/components_page/components/modal/dismiss.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | modal = html.Div( 5 | [ 6 | dbc.Button("Open modal", id="open-dismiss"), 7 | dbc.Modal( 8 | [ 9 | dbc.ModalHeader(dbc.ModalTitle("Dismissing"), close_button=False), 10 | dbc.ModalBody( 11 | "This modal has no close button and can't be dismissed by " 12 | "pressing ESC. Try clicking on the backdrop or the below " 13 | "close button." 14 | ), 15 | dbc.ModalFooter(dbc.Button("Close", id="close-dismiss")), 16 | ], 17 | id="modal-dismiss", 18 | keyboard=False, 19 | backdrop="static", 20 | ), 21 | ], 22 | ) 23 | 24 | 25 | @app.callback( 26 | Output("modal-dismiss", "is_open"), 27 | [Input("open-dismiss", "n_clicks"), Input("close-dismiss", "n_clicks")], 28 | [State("modal-dismiss", "is_open")], 29 | ) 30 | def toggle_modal(n_open, n_close, is_open): 31 | if n_open or n_close: 32 | return not is_open 33 | return is_open 34 | -------------------------------------------------------------------------------- /webpack/config.dist.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var webpack = require('webpack'); 5 | var moduleDefinition = require('./moduleDefinition'); 6 | var directories = require('./directories'); 7 | 8 | var OccurrenceOrderPlugin = require('webpack').optimize.OccurrenceOrderPlugin; 9 | 10 | var NODE_ENV = process.env.NODE_ENV || 'development'; 11 | var environment = JSON.stringify(NODE_ENV); 12 | 13 | var LIBRARY_NAME = 'dash_bootstrap_components'; 14 | var BUILD_PATH = path.join(directories.ROOT, LIBRARY_NAME, '_components'); 15 | 16 | /* eslint-disable no-console */ 17 | console.log('Current environment: ' + environment); 18 | /* eslint-enable no-console */ 19 | 20 | module.exports = { 21 | cache: false, 22 | context: directories.SRC, 23 | mode: NODE_ENV, 24 | externals: { 25 | react: 'React', 26 | 'react-dom': 'ReactDOM' 27 | }, 28 | module: moduleDefinition, 29 | optimization: { 30 | minimize: true, 31 | chunkIds: 'total-size', 32 | moduleIds: 'size' 33 | }, 34 | entry: { 35 | main: './index.js' 36 | }, 37 | output: { 38 | library: LIBRARY_NAME, 39 | libraryTarget: 'window', 40 | path: BUILD_PATH, 41 | filename: LIBRARY_NAME + '.min.js' 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /docs/components_page/components/accordion/callback.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | accordion = html.Div( 5 | [ 6 | dbc.Accordion( 7 | [ 8 | dbc.AccordionItem( 9 | "This is the content of the first section", 10 | title="Item 1", 11 | item_id="item-1", 12 | ), 13 | dbc.AccordionItem( 14 | "This is the content of the second section", 15 | title="Item 2", 16 | item_id="item-2", 17 | ), 18 | dbc.AccordionItem( 19 | "This is the content of the third section", 20 | title="Item 3", 21 | item_id="item-3", 22 | ), 23 | ], 24 | id="accordion", 25 | active_item="item-1", 26 | ), 27 | html.Div(id="accordion-contents", className="mt-3"), 28 | ] 29 | ) 30 | 31 | 32 | @app.callback( 33 | Output("accordion-contents", "children"), 34 | [Input("accordion", "active_item")], 35 | ) 36 | def change_item(item): 37 | return f"Item selected: {item}" 38 | -------------------------------------------------------------------------------- /docs/components_page/components/collapse/horizontal.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | collapse = html.Div( 5 | [ 6 | dbc.Button( 7 | "Open collapse", 8 | id="horizontal-collapse-button", 9 | className="mb-3", 10 | color="primary", 11 | n_clicks=0, 12 | ), 13 | html.Div( 14 | dbc.Collapse( 15 | dbc.Card( 16 | dbc.CardBody( 17 | "This content appeared horizontally due to the " 18 | "`dimension` attribute" 19 | ), 20 | style={"width": "400px"}, 21 | ), 22 | id="horizontal-collapse", 23 | is_open=False, 24 | dimension="width", 25 | ), 26 | style={"minHeight": "100px"}, 27 | ), 28 | ] 29 | ) 30 | 31 | 32 | @app.callback( 33 | Output("horizontal-collapse", "is_open"), 34 | [Input("horizontal-collapse-button", "n_clicks")], 35 | [State("horizontal-collapse", "is_open")], 36 | ) 37 | def toggle_collapse(n, is_open): 38 | if n: 39 | return not is_open 40 | return is_open 41 | -------------------------------------------------------------------------------- /docs/components_page/components/popover/direction.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | 5 | def make_popover(placement): 6 | return dbc.Popover( 7 | [ 8 | dbc.PopoverHeader("Header"), 9 | dbc.PopoverBody(f"This is a {placement} popover"), 10 | ], 11 | id=f"popover-{placement}", 12 | target=f"popover-{placement}-target", 13 | placement=placement, 14 | is_open=False, 15 | ) 16 | 17 | 18 | def make_button(placement): 19 | return dbc.Button( 20 | f"Popover on {placement}", 21 | id=f"popover-{placement}-target", 22 | className="mx-2", 23 | n_clicks=0, 24 | ) 25 | 26 | 27 | popovers = html.Div( 28 | [make_button(p) for p in ["top", "left", "right", "bottom"]] 29 | + [make_popover(p) for p in ["top", "left", "right", "bottom"]] 30 | ) 31 | 32 | 33 | def toggle_popover(n, is_open): 34 | if n: 35 | return not is_open 36 | return is_open 37 | 38 | 39 | for p in ["top", "left", "right", "bottom"]: 40 | app.callback( 41 | Output(f"popover-{p}", "is_open"), 42 | [Input(f"popover-{p}-target", "n_clicks")], 43 | [State(f"popover-{p}", "is_open")], 44 | )(toggle_popover) 45 | -------------------------------------------------------------------------------- /.github/workflows/test-build.yml: -------------------------------------------------------------------------------- 1 | name: Test built package 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | test-build: 10 | if: startsWith(github.head_ref, 'release/') || startsWith(github.head_ref, 'prerelease/') 11 | name: Test build 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | with: 16 | token: ${{ secrets.GH_ACCESS_TOKEN_TOM }} 17 | 18 | - name: Use Node 22 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: 22 22 | 23 | - name: Install the latest version of uv 24 | uses: astral-sh/setup-uv@v3 25 | with: 26 | version: 'latest' 27 | 28 | - name: Install just 29 | uses: extractions/setup-just@v2 30 | 31 | - name: Install JS dependencies 32 | run: npm ci 33 | 34 | - name: Build dash-bootstrap-components 35 | run: just build 36 | 37 | - name: Run tests 38 | run: | 39 | # install the wheel 40 | uv pip install py-dist/dash_bootstrap_components*.whl 41 | # manually invoke pytest inside the .venv 42 | # we can't use uv as `uv run` syncs the source 43 | source .venv/bin/activate 44 | pytest --headless tests 45 | -------------------------------------------------------------------------------- /src/components/form/__tests__/FormText.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import FormText from '../FormText'; 9 | 10 | describe('FormText', () => { 11 | test('renders a small with class "form-text"', () => { 12 | const formText = render(); 13 | 14 | expect(formText.container.querySelector('small.form-text')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const formText = render(Some form text content); 19 | 20 | expect(formText.container).toHaveTextContent('Some form text content'); 21 | }); 22 | 23 | test('applies contextual colors with "color" prop', () => { 24 | const { 25 | container: {firstChild: formTextPrimary} 26 | } = render(); 27 | const { 28 | container: {firstChild: formTextSuccess} 29 | } = render(); 30 | const { 31 | container: {firstChild: formTextDark} 32 | } = render(); 33 | 34 | expect(formTextPrimary).toHaveClass('text-primary'); 35 | expect(formTextSuccess).toHaveClass('text-success'); 36 | expect(formTextDark).toHaveClass('text-dark'); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /docs/components_page/components/card/outline.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | card_content = [ 5 | dbc.CardHeader("Card header"), 6 | dbc.CardBody( 7 | [ 8 | html.H5("Card title", className="card-title"), 9 | html.P( 10 | "This is some card content that we'll reuse", 11 | className="card-text", 12 | ), 13 | ] 14 | ), 15 | ] 16 | 17 | row_1 = dbc.Row( 18 | [ 19 | dbc.Col(dbc.Card(card_content, color="primary", outline=True)), 20 | dbc.Col(dbc.Card(card_content, color="secondary", outline=True)), 21 | dbc.Col(dbc.Card(card_content, color="info", outline=True)), 22 | ], 23 | className="mb-4", 24 | ) 25 | 26 | row_2 = dbc.Row( 27 | [ 28 | dbc.Col(dbc.Card(card_content, color="success", outline=True)), 29 | dbc.Col(dbc.Card(card_content, color="warning", outline=True)), 30 | dbc.Col(dbc.Card(card_content, color="danger", outline=True)), 31 | ], 32 | className="mb-4", 33 | ) 34 | 35 | row_3 = dbc.Row( 36 | [ 37 | dbc.Col(dbc.Card(card_content, color="light", outline=True)), 38 | dbc.Col(dbc.Card(card_content, color="dark", outline=True)), 39 | ] 40 | ) 41 | 42 | cards = html.Div([row_1, row_2, row_3]) 43 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import pluginJs from '@eslint/js'; 2 | import pluginJest from 'eslint-plugin-jest'; 3 | import pluginReact from 'eslint-plugin-react'; 4 | import unusedImports from 'eslint-plugin-unused-imports'; 5 | import globals from 'globals'; 6 | 7 | /** @type {import('eslint').Linter.Config[]} */ 8 | export default [ 9 | { 10 | files: ['**/*.{js,mjs,cjs,jsx}'], 11 | settings: {react: {version: 'detect'}}, 12 | plugins: {jest: pluginJest, 'unused-imports': unusedImports}, 13 | languageOptions: { 14 | globals: pluginJest.environments.globals.globals 15 | }, 16 | rules: { 17 | 'no-unused-vars': 'off', 18 | 'unused-imports/no-unused-imports': 'error', 19 | 'unused-imports/no-unused-vars': [ 20 | 'warn', 21 | { 22 | vars: 'all', 23 | varsIgnorePattern: '^_', 24 | args: 'after-used', 25 | argsIgnorePattern: '^_' 26 | } 27 | ], 28 | 'jest/no-disabled-tests': 'warn', 29 | 'jest/no-focused-tests': 'error', 30 | 'jest/no-identical-title': 'error', 31 | 'jest/prefer-to-have-length': 'warn', 32 | 'jest/valid-expect': 'error' 33 | } 34 | }, 35 | {languageOptions: {globals: globals.browser}}, 36 | 37 | pluginJs.configs.recommended, 38 | pluginReact.configs.flat.recommended 39 | ]; 40 | -------------------------------------------------------------------------------- /docs/components_page/components/input_group.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: InputGroup 3 | lead: Easily extend form controls by adding text, buttons or button groups on either side of `Input`, `Textarea` and `Select` components. 4 | --- 5 | 6 | ## Examples 7 | 8 | Wrap a compatible input component and either a `Button` or `InputGroupText` in an `InputGroup`. 9 | 10 | {{example:components/input_group/simple.py:input_groups}} 11 | 12 | ## Sizing 13 | 14 | Use the `size` argument of `InputGroup` to set the size of all the contents, including inputs and addons. Possible options are `'lg'`, `'md'` (the default), and `'sm'` for large, medium and small respectively. 15 | 16 | {{example:components/input_group/size.py:input_group}} 17 | 18 | ## Checkboxes and radios 19 | 20 | You can place a `Checkbox` or `RadioButton` inside the `InputGroupText` instead of just text. 21 | 22 | {{example:components/input_group/check_radio.py:input_groups}} 23 | 24 | ## Button addons 25 | 26 | Buttons can be placed inside an `InputGroup` 27 | 28 | {{example:components/input_group/button.py:input_group}} 29 | 30 | ## DropdownMenu addons 31 | 32 | And so can `DropdownMenu` components. 33 | 34 | {{example:components/input_group/dropdown.py:input_group}} 35 | 36 | {{apidoc:src/components/input/InputGroup.js}} 37 | 38 | {{apidoc:src/components/input/InputGroupText.js}} 39 | -------------------------------------------------------------------------------- /docs/components_page/components/alert/icon.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | alerts = html.Div( 5 | [ 6 | dbc.Alert( 7 | [ 8 | html.I(className="bi bi-info-circle-fill me-2"), 9 | "An example info alert with an icon", 10 | ], 11 | color="info", 12 | className="d-flex align-items-center", 13 | ), 14 | dbc.Alert( 15 | [ 16 | html.I(className="bi bi-check-circle-fill me-2"), 17 | "An example success alert with an icon", 18 | ], 19 | color="success", 20 | className="d-flex align-items-center", 21 | ), 22 | dbc.Alert( 23 | [ 24 | html.I(className="bi bi-exclamation-triangle-fill me-2"), 25 | "An example warning alert with an icon", 26 | ], 27 | color="warning", 28 | className="d-flex align-items-center", 29 | ), 30 | dbc.Alert( 31 | [ 32 | html.I(className="bi bi-x-octagon-fill me-2"), 33 | "An example danger alert with an icon", 34 | ], 35 | color="danger", 36 | className="d-flex align-items-center", 37 | ), 38 | ] 39 | ) 40 | -------------------------------------------------------------------------------- /docs/components_page/components/card/sizing/utility.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | cards = html.Div( 5 | [ 6 | dbc.Card( 7 | dbc.CardBody( 8 | [ 9 | html.H5("75% width card", className="card-title"), 10 | html.P( 11 | [ 12 | "This card uses the ", 13 | html.Code("w-75"), 14 | " class to set the width to 75%", 15 | ], 16 | className="card-text", 17 | ), 18 | ] 19 | ), 20 | className="w-75 mb-3", 21 | ), 22 | dbc.Card( 23 | dbc.CardBody( 24 | [ 25 | html.H5("50% width card", className="card-title"), 26 | html.P( 27 | [ 28 | "This card uses the ", 29 | html.Code("w-50"), 30 | " class to set the width to 50%", 31 | ], 32 | className="card-text", 33 | ), 34 | ] 35 | ), 36 | className="w-50", 37 | ), 38 | ] 39 | ) 40 | -------------------------------------------------------------------------------- /docs/components_page/components/jumbotron/custom.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | left_jumbotron = dbc.Col( 5 | html.Div( 6 | [ 7 | html.H2("Change the background", className="display-3"), 8 | html.Hr(className="my-2"), 9 | html.P( 10 | "Swap the background-color utility and add a `.text-*` color " 11 | "utility to mix up the look." 12 | ), 13 | dbc.Button("Example Button", color="light", outline=True), 14 | ], 15 | className="h-100 p-5 text-white bg-primary rounded-3", 16 | ), 17 | md=6, 18 | ) 19 | 20 | right_jumbotron = dbc.Col( 21 | html.Div( 22 | [ 23 | html.H2("Add borders", className="display-3"), 24 | html.Hr(className="my-2"), 25 | html.P( 26 | "Or, keep it light and add a border for some added definition " 27 | "to the boundaries of your content." 28 | ), 29 | dbc.Button("Example Button", color="secondary", outline=True), 30 | ], 31 | className="h-100 p-5 bg-light text-dark border rounded-3", 32 | ), 33 | md=6, 34 | ) 35 | 36 | jumbotron = dbc.Row( 37 | [left_jumbotron, right_jumbotron], 38 | className="align-items-md-stretch", 39 | ) 40 | -------------------------------------------------------------------------------- /docs/components_page/components/list_group/content.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | list_group = dbc.ListGroup( 5 | [ 6 | dbc.ListGroupItem( 7 | [ 8 | html.Div( 9 | [ 10 | html.H5("This item has a heading", className="mb-1"), 11 | html.Small("Yay!", className="text-success"), 12 | ], 13 | className="d-flex w-100 justify-content-between", 14 | ), 15 | html.P("And some text underneath", className="mb-1"), 16 | html.Small("Plus some small print.", className="text-muted"), 17 | ] 18 | ), 19 | dbc.ListGroupItem( 20 | [ 21 | html.Div( 22 | [ 23 | html.H5("This item also has a heading", className="mb-1"), 24 | html.Small("Ok!", className="text-warning"), 25 | ], 26 | className="d-flex w-100 justify-content-between", 27 | ), 28 | html.P("And some more text underneath too", className="mb-1"), 29 | html.Small("Plus even more small print.", className="text-muted"), 30 | ] 31 | ), 32 | ] 33 | ) 34 | -------------------------------------------------------------------------------- /src/components/layout/__tests__/Stack.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import Stack from '../Stack'; 9 | 10 | describe('Stack', () => { 11 | test('renders a div with class "vstack"', () => { 12 | const stack = render(); 13 | 14 | expect(stack.container.querySelector('div.vstack')).not.toBe(null); 15 | }); 16 | 17 | test('renders its content', () => { 18 | const stack = render( 19 | 20 |
First item
21 |
Second item
22 |
Third item
23 |
24 | ); 25 | 26 | expect(stack.container).toHaveTextContent('First item'); 27 | expect(stack.container).toHaveTextContent('Second item'); 28 | expect(stack.container).toHaveTextContent('Third item'); 29 | }); 30 | 31 | test('renders a div with class hstack if direction is "horizontal"', () => { 32 | const { 33 | container: {firstChild: stack} 34 | } = render(); 35 | 36 | expect(stack).toHaveClass('hstack'); 37 | }); 38 | 39 | test('gap changes the gap class of the object', () => { 40 | const stack = render(); 41 | 42 | expect(stack.container.querySelector('div.gap-3')).not.toBe(null); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /src/components/nav/__tests__/NavbarToggler.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | import userEvent from '@testing-library/user-event'; 8 | 9 | import NavbarToggler from '../NavbarToggler'; 10 | 11 | describe('NavbarToggler', () => { 12 | test('renders a navbarToggler with class "navbar-toggler"', () => { 13 | const {container} = render(); 14 | 15 | expect(container.querySelector('button.navbar-toggler')).not.toBe(null); 16 | }); 17 | 18 | test('renders its content', () => { 19 | const {container} = render( 20 | Some navbarToggler content 21 | ); 22 | 23 | expect(container).toHaveTextContent('Some navbarToggler content'); 24 | }); 25 | 26 | test('tracks clicks with n_clicks', async () => { 27 | const user = userEvent.setup(); 28 | const mockSetProps = jest.fn(); 29 | const navbarToggler = render( 30 | Clickable 31 | ); 32 | 33 | expect(mockSetProps.mock.calls).toHaveLength(0); 34 | 35 | await user.click(navbarToggler.getByText('Clickable')); 36 | 37 | expect(mockSetProps.mock.calls).toHaveLength(1); 38 | expect(mockSetProps.mock.calls[0][0].n_clicks).toBe(1); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /docs/components_page/components/table/color.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | color_selector = html.Div( 5 | [ 6 | html.Div("Select a colour theme:"), 7 | dbc.Select( 8 | id="change-table-color", 9 | options=[ 10 | {"label": "primary", "value": "primary"}, 11 | {"label": "secondary", "value": "secondary"}, 12 | {"label": "success", "value": "success"}, 13 | {"label": "danger", "value": "danger"}, 14 | {"label": "warning", "value": "warning"}, 15 | {"label": "info", "value": "info"}, 16 | {"label": "light", "value": "light"}, 17 | {"label": "dark", "value": "dark"}, 18 | ], 19 | value="primary", 20 | ), 21 | ], 22 | className="p-3 m-2 border", 23 | ) 24 | 25 | table = html.Div( 26 | [ 27 | color_selector, 28 | dbc.Table( 29 | # using the same table as in the above example 30 | table_header + table_body, 31 | id="table-color", 32 | color="primary", 33 | ), 34 | ] 35 | ) 36 | 37 | 38 | @app.callback(Output("table-color", "color"), Input("change-table-color", "value")) 39 | def change_table_colour(color): 40 | return color 41 | -------------------------------------------------------------------------------- /docs/components_page/components/accordion/always_open_callback.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | accordion = html.Div( 5 | [ 6 | dbc.Accordion( 7 | [ 8 | dbc.AccordionItem( 9 | "This is the content of the first section. It has a " 10 | "default ID of item-0.", 11 | title="Item 1: item-0", 12 | ), 13 | dbc.AccordionItem( 14 | "This is the content of the second section. It has a " 15 | "default ID of item-1.", 16 | title="Item 2: item-1", 17 | ), 18 | dbc.AccordionItem( 19 | "This is the content of the third section. It has a " 20 | "default ID of item-2.", 21 | title="Item 3: item-2", 22 | ), 23 | ], 24 | id="accordion-always-open", 25 | always_open=True, 26 | ), 27 | html.Div(id="accordion-contents-open-ids", className="mt-3"), 28 | ] 29 | ) 30 | 31 | 32 | @app.callback( 33 | Output("accordion-contents-open-ids", "children"), 34 | [Input("accordion-always-open", "active_item")], 35 | ) 36 | def change_item(item): 37 | return f"Item(s) selected: {item}" 38 | -------------------------------------------------------------------------------- /docs/demos/theme_explorer/list_group.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | from .util import make_subheading 5 | 6 | list_group = html.Div( 7 | [ 8 | make_subheading("ListGroup", "list_group"), 9 | dbc.ListGroup( 10 | [ 11 | dbc.ListGroupItem("No color applied"), 12 | dbc.ListGroupItem("The primary item", color="primary"), 13 | dbc.ListGroupItem("A secondary item", color="secondary"), 14 | dbc.ListGroupItem("A successful item", color="success"), 15 | dbc.ListGroupItem("A warning item", color="warning"), 16 | dbc.ListGroupItem("A dangerous item", color="danger"), 17 | dbc.ListGroupItem("An informative item", color="info"), 18 | dbc.ListGroupItem("A light item", color="light"), 19 | dbc.ListGroupItem("A dark item", color="dark"), 20 | dbc.ListGroupItem("An action item", action=True), 21 | dbc.ListGroupItem("An active item", active=True), 22 | dbc.ListGroupItem( 23 | [ 24 | html.H5("Item 4 heading"), 25 | html.P("Item 4 text"), 26 | ] 27 | ), 28 | ] 29 | ), 30 | ], 31 | className="mb-4", 32 | ) 33 | -------------------------------------------------------------------------------- /docs/components_page/components/layout/vertical.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | row = html.Div( 5 | [ 6 | dbc.Row( 7 | [ 8 | dbc.Col(html.Div("One of three columns")), 9 | dbc.Col(html.Div("One of three columns")), 10 | dbc.Col(html.Div("One of three columns")), 11 | ], 12 | align="start", 13 | ), 14 | dbc.Row( 15 | [ 16 | dbc.Col(html.Div("One of three columns")), 17 | dbc.Col(html.Div("One of three columns")), 18 | dbc.Col(html.Div("One of three columns")), 19 | ], 20 | align="center", 21 | ), 22 | dbc.Row( 23 | [ 24 | dbc.Col(html.Div("One of three columns")), 25 | dbc.Col(html.Div("One of three columns")), 26 | dbc.Col(html.Div("One of three columns")), 27 | ], 28 | align="end", 29 | ), 30 | dbc.Row( 31 | [ 32 | dbc.Col(html.Div("One of three columns"), align="start"), 33 | dbc.Col(html.Div("One of three columns"), align="center"), 34 | dbc.Col(html.Div("One of three columns"), align="end"), 35 | ] 36 | ), 37 | ], 38 | className="pad-row", 39 | ) 40 | -------------------------------------------------------------------------------- /src/components/input/__tests__/InputGroup.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment jsdom 3 | */ 4 | import React from 'react'; 5 | 6 | import {render} from '@testing-library/react'; 7 | 8 | import Input from '../Input'; 9 | import InputGroup from '../InputGroup'; 10 | import InputGroupText from '../InputGroupText'; 11 | 12 | describe('InputGroup', () => { 13 | test('renders a div with class "input-group"', () => { 14 | const inputGroup = render(); 15 | 16 | expect(inputGroup.container.querySelector('div.input-group')).not.toBe( 17 | null 18 | ); 19 | }); 20 | 21 | test('renders its content', () => { 22 | const inputGroup = render( 23 | 24 | Addon 25 | 26 | 27 | ); 28 | 29 | expect(inputGroup.container).toHaveTextContent('Addon'); 30 | expect(inputGroup.container.querySelector('input.form-control')).not.toBe( 31 | null 32 | ); 33 | }); 34 | 35 | test('applies sizing CSS classes', () => { 36 | // inputGroup sizes 37 | const { 38 | container: {firstChild: inputGroupSm} 39 | } = render(); 40 | const { 41 | container: {firstChild: inputGroupLg} 42 | } = render(); 43 | 44 | expect(inputGroupSm).toHaveClass('input-group-sm'); 45 | expect(inputGroupLg).toHaveClass('input-group-lg'); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /docs/components_page/components/card/color.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | card_content = [ 5 | dbc.CardHeader("Card header"), 6 | dbc.CardBody( 7 | [ 8 | html.H5("Card title", className="card-title"), 9 | html.P( 10 | "This is some card content that we'll reuse", 11 | className="card-text", 12 | ), 13 | ] 14 | ), 15 | ] 16 | 17 | cards = html.Div( 18 | [ 19 | dbc.Row( 20 | [ 21 | dbc.Col(dbc.Card(card_content, color="primary", inverse=True)), 22 | dbc.Col(dbc.Card(card_content, color="secondary", inverse=True)), 23 | dbc.Col(dbc.Card(card_content, color="info", inverse=True)), 24 | ], 25 | className="mb-4", 26 | ), 27 | dbc.Row( 28 | [ 29 | dbc.Col(dbc.Card(card_content, color="success", inverse=True)), 30 | dbc.Col(dbc.Card(card_content, color="warning", inverse=True)), 31 | dbc.Col(dbc.Card(card_content, color="danger", inverse=True)), 32 | ], 33 | className="mb-4", 34 | ), 35 | dbc.Row( 36 | [ 37 | dbc.Col(dbc.Card(card_content, color="light")), 38 | dbc.Col(dbc.Card(card_content, color="dark", inverse=True)), 39 | ] 40 | ), 41 | ] 42 | ) 43 | -------------------------------------------------------------------------------- /examples/templates/multi-page-apps/responsive-sidebar/assets/responsive-sidebar.css: -------------------------------------------------------------------------------- 1 | #sidebar { 2 | text-align: center; 3 | padding: 2rem 1rem; 4 | background-color: #f8f9fa; 5 | } 6 | 7 | #sidebar h2 { 8 | text-align: left; 9 | margin-bottom: 0; 10 | } 11 | 12 | /* Hide the blurb on a small screen */ 13 | #blurb { 14 | display: none; 15 | } 16 | 17 | #collapse *:first-child { 18 | margin-top: 1rem; 19 | } 20 | 21 | #page-content { 22 | padding: 2rem 1rem; 23 | } 24 | 25 | /* add the three horizontal bars icon for the toggle */ 26 | .navbar-toggler-icon { 27 | background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); 28 | } 29 | 30 | @media (min-width: 48em) { 31 | #sidebar { 32 | position: fixed; 33 | top: 0; 34 | left: 0; 35 | bottom: 0; 36 | width: 16rem; 37 | text-align: left; 38 | } 39 | 40 | /* reveal the blurb on a large screen */ 41 | #blurb { 42 | display: block; 43 | } 44 | 45 | /* Hide the toggle on a large screen */ 46 | #toggle { 47 | display: none; 48 | } 49 | 50 | #collapse { 51 | display: block; 52 | } 53 | 54 | #collapse *:first-child { 55 | margin-top: 0; 56 | } 57 | 58 | #page-content { 59 | margin-left: 18rem; 60 | margin-right: 2rem; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /webpack/config.demo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var webpack = require('webpack'); 5 | var moduleDefinition = require('./moduleDefinition'); 6 | var directories = require('./directories'); 7 | 8 | var NODE_ENV = process.env.NODE_ENV || 'development'; 9 | var environment = JSON.stringify(NODE_ENV); 10 | 11 | var LIBRARY_NAME = 'dash_bootstrap_components'; 12 | var BUILD_PATH = path.join(directories.ROOT, 'demo-lib'); 13 | 14 | var publicHost = process.env.DEMO_PUBLIC_HOST || undefined; 15 | 16 | /* eslint-disable no-console */ 17 | console.log('Current environment: ' + environment); 18 | console.log('Using public host: ' + publicHost || ''); 19 | /* eslint-enable no-console */ 20 | 21 | module.exports = { 22 | cache: false, 23 | context: directories.SRC, 24 | mode: NODE_ENV, 25 | module: moduleDefinition, 26 | plugins: [ 27 | new webpack.DefinePlugin({ 28 | 'process.env': { 29 | NODE_ENV: environment 30 | } 31 | }) 32 | ], 33 | entry: { 34 | bundle: [path.join(directories.ROOT, 'demo/index.js')] 35 | }, 36 | devServer: { 37 | static: 'demo', 38 | compress: true, 39 | port: 9000 40 | }, 41 | output: { 42 | library: LIBRARY_NAME, 43 | libraryTarget: 'this', // Could be 'umd' 44 | path: BUILD_PATH, 45 | pathinfo: true, 46 | publicPath: '/demo-lib/', // For loading from webpack dev server 47 | filename: '[name].js' 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /docs/components_page/components/alert.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Alerts 3 | lead: Provide contextual feedback messages for user actions with the `Alert` component. 4 | --- 5 | 6 | ## Examples 7 | 8 | Set the color of `Alert` using the `color` argument and one of the eight supported contextual color names. 9 | 10 | {{example:components/alert/simple.py:alerts}} 11 | 12 | ## Link color 13 | 14 | The Bootstrap `alert-link` class can be used to color match links inside alerts to the color of the alert. 15 | 16 | {{example:components/alert/link.py:alerts}} 17 | 18 | ## Additional content 19 | 20 | Alerts can contain additional HTML elements like headings, paragraphs and dividers. 21 | 22 | {{example:components/alert/content.py:alert}} 23 | 24 | ## Dismissing 25 | 26 | Set `dismissable=True` to add a dismiss button to the alert which closes the alert on click. You can also use the `is_open` property in callbacks to show or hide the alert. By default the alert appears and disappears with a fade animation. To disable this simply set `fade=False`. 27 | 28 | {{example:components/alert/dismiss.py:alert}} 29 | 30 | ## Automatic dismissal 31 | 32 | You can have your `Alert` components dismiss themselves by using the `duration` keyword argument. Specify a duration in milliseconds after which you would like the `Alert` to dismiss itself when it first becomes visible. 33 | 34 | {{example:components/alert/auto_dismiss.py:alert}} 35 | 36 | {{apidoc:src/components/Alert.js}} 37 | -------------------------------------------------------------------------------- /docs/components_page/components/input/radio_check_inline.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import html 3 | 4 | inline_radioitems = html.Div( 5 | [ 6 | dbc.Label("Choose one"), 7 | dbc.RadioItems( 8 | options=[ 9 | {"label": "Option 1", "value": 1}, 10 | {"label": "Option 2", "value": 2}, 11 | ], 12 | value=1, 13 | id="radioitems-inline-input", 14 | inline=True, 15 | ), 16 | ] 17 | ) 18 | 19 | inline_checklist = html.Div( 20 | [ 21 | dbc.Label("Choose a bunch"), 22 | dbc.Checklist( 23 | options=[ 24 | {"label": "Option 1", "value": 1}, 25 | {"label": "Option 2", "value": 2}, 26 | ], 27 | value=[], 28 | id="checklist-inline-input", 29 | inline=True, 30 | ), 31 | ] 32 | ) 33 | 34 | inline_switches = html.Div( 35 | [ 36 | dbc.Label("Toggle a bunch"), 37 | dbc.Checklist( 38 | options=[ 39 | {"label": "Option 1", "value": 1}, 40 | {"label": "Option 2", "value": 2}, 41 | ], 42 | value=[], 43 | id="switches-inline-input", 44 | inline=True, 45 | switch=True, 46 | ), 47 | ] 48 | ) 49 | 50 | inline_inputs = dbc.Form([inline_radioitems, inline_checklist, inline_switches]) 51 | -------------------------------------------------------------------------------- /docs/components_page/components/input/radio_check_standalone.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, html 3 | 4 | standalone_radio_check = html.Div( 5 | [ 6 | html.Div( 7 | [ 8 | dbc.Checkbox( 9 | id="standalone-checkbox", 10 | label="This is a checkbox", 11 | value=False, 12 | ), 13 | dbc.Switch( 14 | id="standalone-switch", 15 | label="This is a toggle switch", 16 | value=False, 17 | ), 18 | dbc.RadioButton( 19 | id="standalone-radio", 20 | label="This is a radio button", 21 | value=False, 22 | ), 23 | ] 24 | ), 25 | html.P(id="standalone-radio-check-output"), 26 | ] 27 | ) 28 | 29 | 30 | @app.callback( 31 | Output("standalone-radio-check-output", "children"), 32 | [ 33 | Input("standalone-checkbox", "value"), 34 | Input("standalone-switch", "value"), 35 | Input("standalone-radio", "value"), 36 | ], 37 | ) 38 | def on_form_change(checkbox_checked, switch_checked, radio_checked): 39 | return ( 40 | f"Selections: Checkbox: {checkbox_checked}, " 41 | f"Toggle Switch: {switch_checked}, " 42 | f"Radio Button: {radio_checked}" 43 | ) 44 | -------------------------------------------------------------------------------- /docs/components_page/components/alert/dismiss.py: -------------------------------------------------------------------------------- 1 | import dash_bootstrap_components as dbc 2 | from dash import Input, Output, State, html 3 | 4 | alert = html.Div( 5 | [ 6 | dbc.Button( 7 | "Toggle alert with fade", 8 | id="alert-toggle-fade", 9 | className="me-1", 10 | n_clicks=0, 11 | ), 12 | dbc.Button("Toggle alert without fade", id="alert-toggle-no-fade", n_clicks=0), 13 | html.Hr(), 14 | dbc.Alert( 15 | "Hello! I am an alert", 16 | id="alert-fade", 17 | dismissable=True, 18 | is_open=True, 19 | ), 20 | dbc.Alert( 21 | "Hello! I am an alert that doesn't fade in or out", 22 | id="alert-no-fade", 23 | dismissable=True, 24 | fade=False, 25 | is_open=True, 26 | ), 27 | ] 28 | ) 29 | 30 | 31 | @app.callback( 32 | Output("alert-fade", "is_open"), 33 | [Input("alert-toggle-fade", "n_clicks")], 34 | [State("alert-fade", "is_open")], 35 | ) 36 | def toggle_alert(n, is_open): 37 | if n: 38 | return not is_open 39 | return is_open 40 | 41 | 42 | @app.callback( 43 | Output("alert-no-fade", "is_open"), 44 | [Input("alert-toggle-no-fade", "n_clicks")], 45 | [State("alert-no-fade", "is_open")], 46 | ) 47 | def toggle_alert_no_fade(n, is_open): 48 | if n: 49 | return not is_open 50 | return is_open 51 | -------------------------------------------------------------------------------- /docs/components_page/components/tooltip.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tooltip 3 | lead: Use the `Tooltip` component to add Bootstrap style tooltips to your app, with no callbacks required. 4 | --- 5 | 6 | ## Examples 7 | 8 | To use the `Tooltip` component, simply add it to the layout of your app, and give it the id of a component in your layout that you would like to use as the target. When the user hovers over the target component, the tooltip will display. There is no need to write any callbacks. 9 | 10 | In the below example we use a `html.Span` component to target a particular word in a piece of text. 11 | 12 | {{example:components/tooltip/tooltip.py:tooltip}} 13 | 14 | ## Placement 15 | 16 | Use the `placement` argument to control the placement of the tooltip. The basic options are `'auto'`, `'top'`, `'left'`, `'right'`, `'bottom'`. You can additionally add `-start` or `-end` to any of these options, e.g. `'top-start'`. 17 | 18 | {{example:components/tooltip/placement.py:tooltips}} 19 | 20 | ## Controlling the Tooltip with callbacks 21 | 22 | The tooltip's visibility can be controlled with callbacks much like a `Popover` component. Simply set the desired value of `is_open` in a callback. If you are manually controlling the value of `is_open`, you may wish to also set `trigger=None`. By default the `Tooltip` will show when the target element is hovered or focused. 23 | 24 | {{example:components/tooltip/tooltip_callback.py:tooltip}} 25 | 26 | {{apidoc:src/components/Tooltip.js}} 27 | -------------------------------------------------------------------------------- /webpack/config.lib.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var webpack = require('webpack'); 5 | var moduleDefinition = require('./moduleDefinition'); 6 | var directories = require('./directories'); 7 | 8 | var OccurrenceOrderPlugin = require('webpack').optimize.OccurrenceOrderPlugin; 9 | 10 | var NODE_ENV = process.env.NODE_ENV || 'development'; 11 | var environment = JSON.stringify(NODE_ENV); 12 | 13 | var LIBRARY_NAME = 'dash-bootstrap-components'; 14 | 15 | /* eslint-disable no-console */ 16 | console.log('Current environment: ' + environment); 17 | /* eslint-enable no-console */ 18 | 19 | module.exports = { 20 | cache: false, 21 | context: directories.SRC, 22 | mode: NODE_ENV, 23 | externals: [ 24 | { 25 | react: { 26 | root: 'React', 27 | commonjs2: 'react', 28 | commonjs: 'react', 29 | amd: 'react' 30 | } 31 | }, 32 | { 33 | 'react-dom': { 34 | root: 'ReactDOM', 35 | commonjs2: 'react-dom', 36 | commonjs: 'react-dom', 37 | amd: 'react-dom' 38 | } 39 | } 40 | ], 41 | module: moduleDefinition, 42 | optimization: { 43 | minimize: true, 44 | chunkIds: 'total-size', 45 | moduleIds: 'size' 46 | }, 47 | entry: { 48 | main: './index.js' 49 | }, 50 | output: { 51 | library: LIBRARY_NAME, 52 | libraryTarget: 'umd', 53 | path: path.join(directories.ROOT, 'lib/'), 54 | filename: LIBRARY_NAME + '.min.js' 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /docs/components_page/components/table.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Table 3 | lead: Add Bootstrap styles HTML tables to your app with the `Table` component. 4 | --- 5 | 6 | ## Examples 7 | 8 | To add a Bootstrap styled table to your app, use `dbc.Table` as a drop-in replacement for `html.Table`, building up the content with `html.Thead`, `html.Tbody`, `html.Th`, `html.Tr` and `html.Td`. 9 | 10 | {{example:components/table/simple.py:table}} 11 | 12 | ## Styling the table 13 | 14 | The style of the table can be modified through a number of available keyword arguments, such as `dark`, `striped`, `bordered` and `hover`. 15 | 16 | {{example:components/table/kwargs.py:table}} 17 | 18 | ### Table Colors 19 | 20 | Alternatively colors can be added with the `color` property. 21 | 22 | {{example:components/table/color.py:table}} 23 | 24 | ## Table from DataFrame 25 | 26 | Manually constructing a HTML table can be tedious. The `Table` component has a `from_dataframe` method which allows you to easily construct a `Table` from a Pandas DataFrame. You will need to have Pandas installed. Either install it yourself or run `pip install -U dash-bootstrap-components[pandas]`. 27 | 28 | {{example:components/table/helper.py:table}} 29 | 30 | ## Table from MultiIndex DataFrame 31 | 32 | If you have a columnar MultiIndex in your Pandas DataFrame, the `from_dataframe` method will automatically merge the relevant header cells for you. 33 | 34 | {{example:components/table/helper_multi.py:table}} 35 | 36 | {{apidoc:src/components/Table.js}} 37 | --------------------------------------------------------------------------------