Custom design for Widgets

Hello :slight_smile:

With some custom CSS and the InlineStyleSheet, you can easily personalize the look and feel of interactive widgets like sliders, dropdowns, switches, and more.
Feel free to use these snippets, share your own ideas, or remix them for your project.

  1. Slider
    Screenshot_20250617_211403
from bokeh.io import show, curdoc
from bokeh.models import Slider, InlineStyleSheet
from bokeh.layouts import column

curdoc().theme = 'dark_minimal'

slider_style = InlineStyleSheet(css="""
/* Host: set the widget's container background */
:host {
  background: #16161e !important;   /* even darker than black for modern dark UI */
  border-radius: 12px !important;
  padding: 12px !important;
  box-shadow: 0 4px 12px #0006 !important;
}
/* Slider title */
:host .bk-slider-title {
  color: #00ffe0 !important;     /* bright cyan for the title */
  font-size: 1.2em !important;
  font-weight: bold !important;
  letter-spacing: 1px !important;
  font-family: 'Fira Code', 'Consolas', 'Menlo', monospace !important;
  margin-bottom: 14px !important;
  text-shadow: 0 2px 12px #00ffe099;
}
/* Track (background) */
:host .noUi-base, :host .noUi-target {
  background: #23233c !important;
    border: 1px solid #2a3132 !important;

}
/* Filled portion */
:host .noUi-connect {
  background: linear-gradient(90deg, #00ffe0 10%, #d810f7 90%) !important;
  box-shadow: 0 0 12px #00ffe099;
  border-radius: 12px !important;
}
/* Handle */
:host .noUi-handle {
  background: #343838 !important;
  border: 2px solid #00ffe0 !important;
  border-radius: 50%;
  width: 20px;
  height: 20px;
}
/* Handle hover/focus */
:host .noUi-handle:hover, :host .noUi-handle:focus {
  border-color: #ff2a68 !important;
  box-shadow: 0 0 10px #ff2a6890;
}
/* Tooltip */
:host .noUi-tooltip {
  background: #343838 !important;
  color: #00ffe0 !important;
  font-family: 'Consolas', monospace;
  border-radius: 6px;
  border: 1px solid #00ffe0;
}
""")

slider = Slider(
    start=0, end=100, value=42, step=1, 
    title="💠 Custom Neon Slider", width=350, stylesheets=[slider_style]
)

show(column(slider))
  1. Select
from bokeh.io import show, curdoc
from bokeh.models import Select, InlineStyleSheet
from bokeh.layouts import column

select_css = InlineStyleSheet(css="""
/* Widget container */
:host {
    background: #181824 !important;
    border-radius: 14px !important;
    padding: 16px !important;
    box-shadow: 0 4px 24px #0007 !important;
}
/* Title styling */
:host .bk-input-group label, :host .bk-select-title {
    color: #06f0ff !important;
    font-size: 1.18em !important;
    font-family: 'Fira Code', monospace;
    font-weight: bold !important;
    margin-bottom: 12px !important;
    letter-spacing: 1px !important;
    text-shadow: 0 2px 12px #06f0ff88, 0 1px 6px #111b;
}
/* Dropdown select */
:host select {
    background: #23233c !important;
    color: #f9fafb !important;
    border: 2px solid #06b6d4 !important;
    border-radius: 8px !important;
    padding: 10px 14px !important;
    font-size: 1.07em !important;
    transition: border 0.1s, box-shadow 0.1s;
    box-shadow: none !important;
}
/* Glow effect on hover/focus */
:host select:hover, :host select:focus {
    border-color: #ff3049 !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 18px #ff3049cc !important;
    outline: none !important;
}

""")

select = Select(
    title="💠 Select a Framework", 
    options=["React", "Vue.js", "Svelte"], 
    value="React", 
    width=350, 
    stylesheets=[select_css]
)

show(column(select))

  1. Multichoice
from bokeh.io import show, curdoc
from bokeh.models import MultiChoice, InlineStyleSheet
from bokeh.layouts import column

multi_style = InlineStyleSheet(css="""
/* Outer widget container */
:host {
    background: #181824 !important;
    border-radius: 14px !important;
    padding: 16px !important;
    box-shadow: 0 4px 20px #0008 !important;
}
/* Title styling */
:host .bk-input-group label, :host .bk-multichoice-title {
    color: #00ffe0 !important;
    font-size: 1.18em !important;
    font-family: 'Fira Code', monospace;
    font-weight: bold !important;
    margin-bottom: 10px !important;
    letter-spacing: 1px !important;
    text-shadow: 0 2px 12px #00ffe088, 0 1px 4px #181824;
}
/* The input field when closed */
:host .choices__inner {
    background: #23233c !important;
    color: #f9fafb !important;
    border: 2px solid #06b6d4 !important;
    border-radius: 8px !important;
    font-size: 1.05em !important;
    transition: border 0.1s, box-shadow 0.1s;
    box-shadow: none !important;
}
/* Glow on hover/focus of input */
:host .choices__inner:hover, :host .choices__inner:focus-within {
    border-color: #ff3049 !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 16px #ff3049cc !important;
    outline: none !important;
}
/* Dropdown list */
:host .choices__list--dropdown {
    background: #181824 !important;
    border: 1.5px solid #06b6d4 !important;
    border-radius: 8px !important;
    box-shadow: 0 10px 32px #000c !important;
}
/* Items in the dropdown */
:host .choices__item--choice {
    color: #f9fafb !important;
    padding: 12px 16px !important;
    transition: all 0.15s;
    border-bottom: 1px solid #28284666 !important;
}
:host .choices__item--choice:hover {
    background: #8b5cf6 !important;
    color: #1f2937 !important;
}
/* Active selected items in the box */
:host .choices__item--selectable {
    background: linear-gradient(90deg, #ffb028 20%, #ff4f4f 100%) !important;
    color: #181824 !important;
    border-radius: 6px !important;
    font-weight: 600 !important;
    margin: 2px 4px !important;
    padding: 6px 14px !important;
    box-shadow: 0 1px 6px #0005;
}
""")

multi = MultiChoice(
    title="🌒 Pick Languages", 
    options=["Python", "JS", "Rust", "FORTRAN", "C++", "C#", "R", "Ruby", "PHP", "Java"], 
    value=["Python"], 
    width=350, 
    stylesheets=[multi_style]
)

show(column(multi))

  1. Input
from bokeh.io import show, curdoc
from bokeh.models import TextInput, InlineStyleSheet
from bokeh.layouts import column

textinput_css = InlineStyleSheet(css="""
/* Outer container styling */
:host {
    background: #181824 !important;
    border-radius: 14px !important;
    padding: 16px !important;
    box-shadow: 0 4px 18px #0006 !important;
}
/* Title label styling */
:host .bk-input-group label, :host .bk-textinput-title {
    color: #34ffe0 !important;
    font-size: 1.14em !important;
    font-family: 'Fira Code', monospace;
    font-weight: bold !important;
    margin-bottom: 12px !important;
    letter-spacing: 0.5px !important;
    text-shadow: 0 2px 12px #34ffe077, 0 1px 3px #222;
}
/* The input box */
:host input[type="text"] {
    background: #23233c !important;
    color: #f9fafb !important;
    border: 2px solid #06b6d4 !important;
    border-radius: 8px !important;
    padding: 11px 15px !important;
    font-size: 1.08em !important;
    transition: border 0.12s, box-shadow 0.12s;
    box-shadow: none !important;
}
/* On hover/focus: red border with glowing effect */
:host input[type="text"]:hover,
:host input[type="text"]:focus {
    border-color: #ff3049 !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 15px #ff3049bb !important;
    outline: none !important;
}
/* Placeholder text */
:host input[type="text"]::placeholder {
    color: #9ca3af !important;
    opacity: 0.7 !important;
    font-style: italic !important;
}
""")

ti = TextInput(
    title="💻 Project Name",
    placeholder="Type here...",
    width=350,
    stylesheets=[textinput_css]
)

show(column(ti))

  1. RangeSlider
from bokeh.io import show
from bokeh.models import RangeSlider, InlineStyleSheet

# Modern dark theme CSS variables
base_variables = """
:host {
    --primary-color: #8b5cf6;
    --secondary-color: #06b6d4;
    --background-color: #181824;
    --surface-color: #23233c;
    --text-color: #f9fafb;
    --accent-color: #f59e0b;
    --danger-color: #ff3049;
    --border-color: #4b5563;
}
"""

range_slider_style = InlineStyleSheet(css=base_variables + """
:host {
    background: var(--background-color) !important;
    border-radius: 14px !important;
    padding: 18px !important;
    box-shadow: 0 4px 18px #0006 !important;
}
/* Title styling */
:host .bk-slider-title {
    color: var(--accent-color) !important;
    font-size: 1.16em !important;
    font-family: 'Fira Code', monospace;
    font-weight: bold !important;
    margin-bottom: 13px !important;
    letter-spacing: 1px;
    text-shadow: 0 2px 8px #f59e0b77;
}
/* Slider rail */
:host .noUi-target {
    background: var(--surface-color) !important;
    border: 2px solid var(--border-color) !important;
    border-radius: 7px !important;
    box-shadow: none !important;
    height: 12px !important;
}
/* Active track with orange gradient */
:host .noUi-connect {
    background: linear-gradient(90deg, var(--accent-color), var(--primary-color)) !important;
    border-radius: 6px !important;
    box-shadow: 0 1px 10px var(--accent-color)44;
}
/* Handles */
:host .noUi-handle {
    background: var(--text-color) !important;
    border: 3px solid var(--accent-color) !important;
    border-radius: 50% !important;
    width: 26px !important;
    height: 26px !important;
    box-shadow: 0 3px 8px rgba(0,0,0,0.3) !important;
    cursor: grab !important;
    transition: border 0.13s, box-shadow 0.13s;
}
/* Orange glow on hover, red glow on focus/active */
:host .noUi-handle:hover {
    border-color: var(--accent-color) !important;
    box-shadow: 0 0 0 2px #f59e0b99, 0 0 15px #f59e0bcc !important;
}
:host .noUi-handle:focus, :host .noUi-handle:active {
    border-color: var(--danger-color) !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 18px #ff3049cc !important;
    outline: none !important;
    cursor: grabbing !important;
    transform: scale(1.07) !important;
}
/* Tooltip bubble styling */
:host .noUi-tooltip {
    background: var(--surface-color) !important;
    color: var(--accent-color) !important;
    font-family: 'Fira Code', monospace;
    border-radius: 8px;
    border: 1.5px solid var(--accent-color);
    box-shadow: 0 2px 8px #0004;
}
""")

range_slider = RangeSlider(
    start=0, 
    end=100, 
    value=(20, 80), 
    step=5,
    title="💰 Budget Range ($K)",
    width=350,
    stylesheets=[range_slider_style]
)

show(range_slider)
  1. Button
    Screenshot_20250617_205528

from bokeh.io import show
from bokeh.models import Button, InlineStyleSheet
# Common CSS variables for consistent theming
base_variables = """
:host {
    /* CSS Custom Properties for easy theming */
    --primary-color: #8b5cf6;
    --secondary-color: #06b6d4;
    --background-color: #1f2937;
    --surface-color: #343838;
    --text-color: #f9fafb;
    --accent-color: #f59e0b;
    --danger-color: #ef4444;
    --success-color: #10b981;
    --border-color: #4b5563;
    --hover-color: #6366f1;
    
    background: none !important;
}
"""
button_style = InlineStyleSheet(css=base_variables + """
:host button {
    background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)) !important;
    color: white !important;
    border: none !important;
    border-radius: 6px !important;
    padding: 10px 20px !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    cursor: pointer !important;
    transition: all 0.2s ease !important;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
}

:host button:hover {
    transform: translateY(-1px) !important;
    box-shadow: 0 4px 8px rgba(0,0,0,0.2) !important;
    background: linear-gradient(135deg, var(--hover-color), var(--primary-color)) !important;
}

:host button:active {
    transform: translateY(0) !important;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
}

:host button:disabled {
    background: #6b7280 !important;
    cursor: not-allowed !important;
    transform: none !important;
    box-shadow: none !important;
}
""")
button = Button(
    label="🚀 Deploy Project",
    button_type="primary",
    width=200,
    stylesheets=[button_style]
)
show(button)
  1. Checkbox

from bokeh.io import show
from bokeh.models import CheckboxGroup, InlineStyleSheet

# Common CSS variables for consistent theming
base_variables = """
:host {
    /* CSS Custom Properties for easy theming */
    --primary-color: #8b5cf6;
    --secondary-color: #06b6d4;
    --background-color: #1f2937;
    --surface-color: #343838;
    --text-color: #f9fafb;
    --accent-color: #f59e0b;
    --danger-color: #ef4444;
    --success-color: #10b981;
    --border-color: #4b5563;
    --hover-color: #6366f1;
    
    background: none !important;
}
"""
checkbox_style = InlineStyleSheet(css=base_variables + """
:host .bk-input-group {
    background: var(--surface-color) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 6px !important;
    padding: 8px !important;
}

:host input[type="checkbox"] {
    appearance: none !important;
    width: 18px !important;
    height: 18px !important;
    border: 2px solid var(--border-color) !important;
    border-radius: 3px !important;
    background: var(--surface-color) !important;
    cursor: pointer !important;
    position: relative !important;
    margin-right: 8px !important;
}

:host input[type="checkbox"]:checked {
    background: var(--primary-color) !important;
    border-color: var(--primary-color) !important;
}

:host input[type="checkbox"]:checked::after {
    content: "✓" !important;
    position: absolute !important;
    top: -2px !important;
    left: 2px !important;
    color: white !important;
    font-size: 12px !important;
    font-weight: bold !important;
}

:host label {
    color: var(--text-color) !important;
    cursor: pointer !important;
    font-size: 14px !important;
    display: flex !important;
    align-items: center !important;
    margin-bottom: 6px !important;
}
""")
checkbox_group = CheckboxGroup(
    labels=["🐛 Enable Debug Mode", "📊 Analytics Tracking", "🔔 Email Notifications", "🌐 Public Access"],
    active=[0, 2],
    width=350,
    stylesheets=[checkbox_style]
)
show(checkbox_group)
  1. RadioButtonGroup
from bokeh.io import show
from bokeh.models import RadioButtonGroup, InlineStyleSheet
from bokeh.layouts import column

radio_btn_css = InlineStyleSheet(css="""
/* Outer container */
:host {
    background: #181824 !important;
    border-radius: 16px !important;
    padding: 22px 22px 18px 22px !important;
    box-shadow: 0 4px 18px #0008 !important;
    max-width: 600px !important;
}
/* Title */
:host .bk-input-group label, :host .bk-radiobuttongroup-title {
    color: #f59e0b !important;
    font-size: 1.16em !important;
    font-family: 'Fira Code', monospace;
    font-weight: bold !important;
    margin-bottom: 16px !important;
    text-shadow: 0 2px 10px #f59e0b99;
    letter-spacing: 0.5px;
}
/* Button group: wrap on small screens */
:host .bk-btn-group {
    display: flex !important;
    gap: 18px !important;
    flex-wrap: wrap !important;
    justify-content: flex-start;
    margin-bottom: 6px;
}
/* Each radio button - pill shape, full text, no ellipsis */
:host button.bk-btn {
    background: #23233c !important;
    color: #f9fafb !important;
    border: 2.5px solid #f59e0b !important;
    border-radius: 999px !important;
    padding: 0.7em 2.2em !important;
    min-width: 120px !important;
    font-size: 1.09em !important;
    font-family: 'Fira Code', monospace;
    font-weight: 600 !important;
    transition: border 0.13s, box-shadow 0.14s, color 0.12s, background 0.13s;
    box-shadow: 0 2px 10px #0002 !important;
    cursor: pointer !important;
    outline: none !important;
    white-space: nowrap !important;
    overflow: visible !important;
    text-overflow: unset !important;
}
/* Orange glow on hover */
:host button.bk-btn:hover:not(.bk-active) {
    border-color: #ffa733 !important;
    color: #ffa733 !important;
    box-shadow: 0 0 0 2px #ffa73399, 0 0 13px #ffa73388 !important;
    background: #2e2937 !important;
}
/* Red glow on active/focus */
:host button.bk-btn:focus, :host button.bk-btn.bk-active {
    border-color: #ff3049 !important;
    color: #ff3049 !important;
    background: #322d36 !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 19px #ff304988 !important;
}
/* Remove focus outline */
:host button.bk-btn:focus {
    outline: none !important;
}
""")

radio_group = RadioButtonGroup(
    labels=["Production", "Staging", "Development", "Testing"],
    active=0,
    width=600,
    stylesheets=[radio_btn_css]
)

show(column(radio_group))

  1. FileInput

from bokeh.io import show
from bokeh.models import FileInput, InlineStyleSheet
base_variables = """
:host {
    /* CSS Custom Properties for easy theming */
    --primary-color: #8b5cf6;
    --secondary-color: #06b6d4;
    --background-color: #1f2937;
    --surface-color: #343838;
    --text-color: #f9fafb;
    --accent-color: #f59e0b;
    --danger-color: #ef4444;
    --success-color: #10b981;
    --border-color: #4b5563;
    --hover-color: #6366f1;
    
    background: none !important;
}
"""
file_input_style = InlineStyleSheet(css=base_variables + """
:host input[type="file"] {
    background: var(--surface-color) !important;
    color: var(--text-color) !important;
    border: 2px dashed var(--border-color) !important;
    border-radius: 6px !important;
    padding: 20px !important;
    font-size: 14px !important;
    cursor: pointer !important;
    transition: all 0.2s ease !important;
}

:host input[type="file"]:hover {
    border-color: var(--primary-color) !important;
    background: rgba(139, 92, 246, 0.05) !important;
}

:host input[type="file"]::file-selector-button {
    background: var(--primary-color) !important;
    color: white !important;
    border: none !important;
    border-radius: 4px !important;
    padding: 8px 16px !important;
    margin-right: 12px !important;
    cursor: pointer !important;
    font-weight: 600 !important;
}
""")
file_input = FileInput(
    title="📁 Upload Configuration:",
    accept=".json,.yaml,.yml,.config",
    width=350,
    stylesheets=[file_input_style]
)
show(file_input)

  1. RadioButton
from bokeh.io import show
from bokeh.models import RadioGroup, InlineStyleSheet
from bokeh.layouts import column

radio_css = InlineStyleSheet(css="""
/* Outer box */
:host {
    background: #181824 !important;
    border-radius: 14px !important;
    padding: 18px !important;
    box-shadow: 0 4px 18px #0007 !important;
}
/* Title (if used) */
:host .bk-input-group label, :host .bk-radiogroup-title {
    color: #f59e0b !important;
    font-size: 1.12em !important;
    font-family: 'Fira Code', monospace;
    font-weight: bold;
    margin-bottom: 11px;
    text-shadow: 0 2px 10px #f59e0b77;
}
/* Radio group styling */
:host .bk-input-group {
    background: #23233c !important;
    border-radius: 8px !important;
    padding: 10px 4px !important;
    border: 2px solid #f59e0b !important;
}
/* Each radio button */
:host input[type="radio"] {
    appearance: none !important;
    background: #23233c !important;
    border: 2px solid #f59e0b !important;
    border-radius: 50% !important;
    width: 19px !important;
    height: 19px !important;
    margin-right: 10px !important;
    vertical-align: middle;
    transition: border 0.12s, box-shadow 0.12s;
    box-shadow: none !important;
}
/* Glow on hover */
:host input[type="radio"]:hover {
    border-color: #ffa733 !important;
    box-shadow: 0 0 0 2px #ffa73399, 0 0 11px #ffa733bb !important;
}
:host input[type="radio"]:focus {
    border-color: #ff3049 !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 13px #ff3049cc !important;
    outline: none !important;
}
/* Checked state */
:host input[type="radio"]:checked {
    border-color: #ff3049 !important;
    background: #f59e0b !important;
}
:host input[type="radio"]:checked::after {
    content: "";
    display: block;
    width: 9px;
    height: 9px;
    margin: 3px auto;
    border-radius: 50%;
    background: #ff3049 !important;
}
/* Label styling */
:host label {
    color: #f9fafb !important;
    font-family: 'Fira Code', monospace;
    font-size: 1.04em;
    margin-bottom: 4px;
    vertical-align: middle;
    cursor: pointer;
}
""")

radio = RadioGroup(
    labels=["Production", "Staging", "Development", "Testing"],
    active=2,
    width=350,
    stylesheets=[radio_css]
)

show(column(radio))
  1. Div
from bokeh.io import show
from bokeh.models import Div

dashboard = Div(
    text="""
    <div style="
        background: linear-gradient(135deg, #343838 60%, #1f2937 100%);
        border: 2.5px solid #f59e0b;
        border-radius: 20px;
        padding: 30px 32px 20px 32px;
        margin: 18px 0;
        min-width: 520px;
        max-width: 720px;
        box-shadow: 0 8px 32px #8b5cf655, 0 2px 24px #000c;
        font-family: 'Fira Code', 'Menlo', 'Consolas', monospace;
    ">
        <h2 style="color: #f59e0b; font-size: 2em; font-weight: bold; margin-top: 0; margin-bottom: 10px; letter-spacing: 1px; text-shadow: 0 2px 20px #f59e0b55;">
            🛠️ Fancy Project Dashboard
        </h2>
        
        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 20px;">
            <div>
                <h4 style="color: #06b6d4; font-size: 1.14em; margin-bottom: 10px;">📋 Project Details</h4>
                <ul style="color: #f9fafb; font-size: 1.07em; padding-left: 17px; margin-top: 0;">
                    <li><strong>Languages:</strong> Python, JS, Rust</li>
                    <li><strong>Framework:</strong> React</li>
                    <li><strong>Name:</strong> NebulaOps</li>
                    <li><strong>Description:</strong> A modern dashboard demo for Bokeh.</li>
                </ul>
            </div>
            <div>
                <h4 style="color: #f59e0b; font-size: 1.14em; margin-bottom: 10px;">⚙️ Configuration</h4>
                <ul style="color: #f9fafb; font-size: 1.07em; padding-left: 17px; margin-top: 0;">
                    <li><strong>Environment:</strong> 🚀 Production</li>
                    <li><strong>Features:</strong> 🐛 Debug, 📊 Analytics</li>
                    <li><strong>Performance:</strong> 8/10</li>
                    <li><strong>Budget:</strong> $25K - $70K</li>
                </ul>
            </div>
        </div>
        
        <div style="margin-top: 14px; padding-top: 15px; border-top: 1px solid #4b5563;">
            <h4 style="color: #10b981; margin-bottom: 10px;">🎯 Deployment Info</h4>
            <ul style="color: #f9fafb; font-size: 1.07em; padding-left: 17px; margin-top: 0;">
                <li><strong>Launch Date:</strong> 2025-06-21</li>
                <li><strong>Team Size:</strong> 7 members</li>
                <li><strong>Status:</strong> Deployed</li>
            </ul>
        </div>
        
        <div style="
            margin-top: 24px; 
            padding: 13px 20px; 
            background: rgba(245, 158, 11, 0.13); 
            border-radius: 8px; 
            border-left: 5px solid #f59e0b;
            box-shadow: 0 1px 8px #f59e0b33;
        ">
            <span style="color: #f59e0b; font-weight: 700; font-size: 1.1em;">
                💡 All systems operational — last checked at 14:20:52
            </span>
        </div>
    </div>
    """,
    width=650, height=410
)

show(dashboard)

  1. Password Input
from bokeh.io import show
from bokeh.models import PasswordInput, InlineStyleSheet
from bokeh.layouts import column

password_css = InlineStyleSheet(css="""
/* Container */
:host {
    background: #181824 !important;
    border-radius: 14px !important;
    padding: 16px !important;
    box-shadow: 0 4px 18px #0006 !important;
}
/* Title */
:host .bk-input-group label, :host .bk-passwordinput-title {
    color: #f59e0b !important;
    font-size: 1.13em !important;
    font-family: 'Fira Code', monospace;
    font-weight: bold;
    margin-bottom: 11px;
    text-shadow: 0 2px 10px #f59e0b99;
}
/* Password field */
:host input[type="password"] {
    background: #23233c !important;
    color: #f9fafb !important;
    border: 2px solid #f59e0b !important;
    border-radius: 8px !important;
    padding: 11px 15px !important;
    font-size: 1.08em !important;
    font-family: 'Fira Code', monospace;
    transition: border 0.12s, box-shadow 0.12s;
    box-shadow: none !important;
    letter-spacing: 0.15em !important;
}
/* Orange glow on hover, red glow on focus */
:host input[type="password"]:hover {
    border-color: #ffa733 !important;
    box-shadow: 0 0 0 2px #ffa73399, 0 0 13px #ffa733bb !important;
}
:host input[type="password"]:focus {
    border-color: #ff3049 !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 15px #ff3049cc !important;
    outline: none !important;
}
/* Placeholder */
:host input[type="password"]::placeholder {
    color: #9ca3af !important;
    opacity: 0.7 !important;
    font-style: italic !important;
}
""")

pw = PasswordInput(
    title="🔑 API Key / Password",
    placeholder="Enter your secret...",
    width=350,
    stylesheets=[password_css]
)

show(column(pw))

Custom design for TabPanel!

Peek 2025-06-28 02-44

from bokeh.io import curdoc
from bokeh.models import TabPanel, Tabs, ColumnDataSource, InlineStyleSheet
from bokeh.plotting import figure
from bokeh.layouts import column
import numpy as np
import pandas as pd
curdoc().theme = 'dark_minimal'
# --- Data setup ---
N = 100
dates = pd.date_range("2016-01-01", periods=N, freq="M")
signal = 5 + 2*np.sin(2*np.pi*(dates.month-1)/12) + np.random.normal(0, 0.7, N)
df = pd.DataFrame({'value': signal}, index=dates)
monthly_means = df.groupby(df.index.month)['value'].transform('mean')
anomalies = df['value'] - monthly_means

source = ColumnDataSource(data=dict(time=dates, value=signal, anomaly=anomalies))

# --- Time Series plot ---
p1 = figure(width=800, height=350, x_axis_type="datetime", title="Time Series", border_fill_color="#2d2d2d")
p1.line('time', 'value', source=source, line_width=2, color="#0af", legend_label="Raw")
p1.legend.location = "top_left"
p1.xaxis.axis_label = "Time"
p1.yaxis.axis_label = "Value"

# --- Anomalies plot ---
p2 = figure(width=800, height=350, x_axis_type="datetime", title="Deseasonalized Anomalies", border_fill_color="#2d2d2d")
p2.line('time', 'anomaly', source=source, line_width=2, color="#e44", legend_label="Deseasonalized")
p2.legend.location = "top_left"
p2.xaxis.axis_label = "Time"
p2.yaxis.axis_label = "Anomaly"

# --- Your InlineStyleSheet for beautiful tabs ---
tabs_style = InlineStyleSheet(css="""
/* Main tabs container */
:host {
    background: #2d2d2d !important;
    border-radius: 14px !important;
    padding: 8px !important;
    margin: 10px !important;
    box-shadow: 0 6px 20px #00ffe055, 0 2px 10px rgba(0, 0, 0, 0.3) !important;
    border: 1px solid rgba(0, 191, 255, 0.3) !important;
}
/* Tab navigation bar */
:host .bk-tabs-header {
    background: transparent !important;
    border-bottom: 2px solid #00bfff !important;
    margin-bottom: 8px !important;
}
/* Individual tab buttons */
:host .bk-tab {
    background: linear-gradient(135deg, #2d2d2d 0%, #3a3a3a 100%) !important;
    color: #00bfff !important;
    border: 1px solid #555 !important;
    border-radius: 8px 8px 0 0 !important;
    padding: 12px 20px !important;
    margin-right: 4px !important;
    font-family: 'Arial', sans-serif !important;
    font-weight: 600 !important;
    font-size: 0.95em !important;
    text-transform: uppercase !important;
    letter-spacing: 0.5px !important;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
    position: relative !important;
    overflow: hidden !important;
}
/* Tab hover effect */
:host .bk-tab:hover {
    background: linear-gradient(135deg, #dc1cdd 0%, #ff1493 100%) !important;
    color: #ffffff !important;
    border-color: #dc1cdd !important;
    box-shadow: 0 4px 15px rgba(220, 28, 221, 0.5) !important;
    transform: translateY(-2px) !important;
}
/* Active tab styling */
:host .bk-tab.bk-active {
    background: linear-gradient(135deg, #00bfff 0%, #0080ff 100%) !important;
    color: #000000 !important;
    border-color: #00bfff !important;
    box-shadow: 0 4px 20px rgba(0, 191, 255, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.3) !important;
    transform: translateY(-1px) !important;
    font-weight: 700 !important;
}
/* Active tab glow effect */
:host .bk-tab.bk-active::before {
    content: '' !important;
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%) !important;
    animation: shimmer 2s infinite !important;
}
@keyframes shimmer {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}
/* Tab content area */
:host .bk-tab-content {
    background: transparent !important;
    padding: 16px !important;
    border-radius: 0 0 10px 10px !important;
}
/* Focus states for accessibility */
:host .bk-tab:focus {
    outline: 2px solid #00bfff !important;
    outline-offset: 2px !important;
}
/* Disabled tab state */
:host .bk-tab:disabled {
    background: #1a1a1a !important;
    color: #666 !important;
    cursor: not-allowed !important;
    opacity: 0.5 !important;
}
""")

# --- Panels and Tabs ---
tabs = Tabs(tabs=[
    TabPanel(child=column(p1), title="Timeseries"),
    TabPanel(child=column(p2), title="Anomalies"),
], stylesheets=[tabs_style], styles={'width':'890px'},)

curdoc().add_root(tabs)

1 Like

Custom design for TextAreaInput.

from bokeh.models import TextAreaInput, InlineStyleSheet
from bokeh.io import show
# Updated stylesheet for TextAreaInput
tais = InlineStyleSheet(css="""
/* Outer container styling */
:host {
    background: #181824 !important;
    border-radius: 14px !important;
    padding: 16px !important;
    box-shadow: 0 4px 18px #0006 !important;
}

/* Title label styling */
:host .bk-input-group label, 
:host .bk-textinput-title {
    color: #34ffe0 !important;
    font-size: 1.14em !important;
    font-family: 'Fira Code', monospace !important;
    font-weight: bold !important;
    margin-bottom: 12px !important;
    letter-spacing: 0.5px !important;
    text-shadow: 0 2px 12px #34ffe077, 0 1px 3px #222 !important;
}

/* The textarea input box - changed from input[type="text"] to textarea */
:host textarea {
    background: #23233c !important;
    color: #f9fafb !important;
    border: 2px solid #06b6d4 !important;
    border-radius: 8px !important;
    padding: 11px 15px !important;
    font-size: 1.08em !important;
    font-family: 'Fira Code', monospace !important;
    transition: border 0.12s ease, box-shadow 0.12s ease !important;
    box-shadow: none !important;
    resize: vertical !important;
    min-height: 120px !important;
}

/* On hover/focus: red border with glowing effect */
:host textarea:hover,
:host textarea:focus {
    border-color: #ff3049 !important;
    box-shadow: 0 0 0 2px #ff304999, 0 0 15px #ff3049bb !important;
    outline: none !important;
}

/* Placeholder text */
:host textarea::placeholder {
    color: #9ca3af !important;
    opacity: 0.7 !important;
    font-style: italic !important;
}

/* Scrollbar styling for webkit browsers */
:host textarea::-webkit-scrollbar {
    width: 8px !important;
}

:host textarea::-webkit-scrollbar-track {
    background: #1a1a2e !important;
    border-radius: 4px !important;
}

:host textarea::-webkit-scrollbar-thumb {
    background: #06b6d4 !important;
    border-radius: 4px !important;
}

:host textarea::-webkit-scrollbar-thumb:hover {
    background: #ff3049 !important;
}
""")

# Fixed TextAreaInput with better configuration
text_area_input = TextAreaInput(
    value="",
    rows=10,
    cols=150,
    title="My notes:",
    placeholder="Start typing your notes here...",
    stylesheets=[tais]
)
show(text_area_input)

Custom design for DataTable:

from bokeh.io import curdoc
from bokeh.models import TableColumn, ColumnDataSource, DataTable, InlineStyleSheet
from bokeh.layouts import column
import numpy as np
import pandas as pd

# --- Example DataFrame ---
np.random.seed(0)
n = 30
df = pd.DataFrame({
    "Year": np.arange(2000, 2000 + n),
    "Value": np.round(np.random.normal(10, 2, n), 2),
    "Anomaly": np.round(np.random.normal(0, 1, n), 2)
})

# --- Bokeh DataTable setup ---
source5 = ColumnDataSource(df)

columns5 = [
    TableColumn(field="Year", title="Year"),
    TableColumn(field="Value", title="Value"),
    TableColumn(field="Anomaly", title="Anomaly")
]

# --- Your custom dark theme stylesheet ---
dark_table_style = InlineStyleSheet(css="""
/* Container styling */
:host {
    background: #2e2e30 !important;
    border-radius: 14px !important;
    padding: 16px !important;
    box-shadow: 0 4px 18px #0006 !important;
    margin: 10px !important;
}

/* Headers */
:host div[class*="header"],
:host div[class*="slick-header"],
:host th,
:host [class*="header"] {
    background: #2e2e30 !important;
    color: #34ffe0 !important;
    font-weight: bold !important;
    font-family: 'Fira Code', monospace !important;
    border-bottom: 1px solid #06b6d4 !important;
}

/* cells */
:host div[class*="cell"],
:host div[class*="slick-cell"],
:host td {
    background: #565755 !important;
    color: #ef5f5f !important;
    border-right: 1px solid #908e8e !important;
    border-bottom: 1px solid #908e8e !important;
    font-family: 'Fira Code', monospace !important;
    font-size: 1.2em !important;

}

/* Alternating rows */
:host div[class*="row"]:nth-child(even) div[class*="cell"],
:host div[class*="slick-row"]:nth-child(even) div[class*="slick-cell"],
:host tr:nth-child(even) td {
    background: #2a2a2c !important;
    color: #ffb907 !important;
    border-right: 1px solid #908e8e !important;
    border-bottom: 1px solid #908e8e !important;
    font-family: 'Fira Code', monospace !important;
    font-size: 0.9em !important;
}

/* Hover effects */
:host div[class*="row"]:hover div[class*="cell"],
:host div[class*="slick-row"]:hover div[class*="slick-cell"],
:host tr:hover td {
    background: #3eafff !important;
    color: #0c0c0c !important;
    border-color: #ff0000 !important;
    border-style: solid !important;
    border-width: 1px !important;
}

/* Selected cells */
:host div[class*="slick-cell"][class*="selected"],
:host div[class*="cell"][class*="selected"] {
    background: pink !important;
    color: red !important;
    border: 1px solid #ff1493 !important;
}
                                    
/* Selected cells */
:host div[class*="row"]:nth-child(even) div[class*="cell"][class*="selected"],
:host div[class*="slick-row"]:nth-child(even) div[class*="slick-cell"][class*="selected"]{
    background: pink !important;
    color: black !important;
    border: 1px solid #ff1493 !important;
}

/* Scrollbars */
:host *::-webkit-scrollbar {
    width: 9px !important;
    height: 8px !important;
    background: #1a1a2e !important;
}
:host *::-webkit-scrollbar-thumb {
    background: #06b6d4 !important;
    border-radius: 4px !important;
}
:host *::-webkit-scrollbar-track {
    background: #1c2e1a !important;
    border-radius: 4px !important;
}
/* Firefox scrollbars */
:host .bk-data-table {
    scrollbar-color: #06b6d4 #1c2e1a !important;
    scrollbar-width: thin !important;
}

/* But restore specific dark backgrounds where needed */
:host div[class*="header"] * {
    background-color: #1a1a2e !important;
}

:host [class*="header"] * {
    color: #34ffe0 !important;
}
""")

# --- DataTable Widget ---
data_table = DataTable(
    source=source5,
    columns=columns5,
    width=500,
    height=450,
    row_height=21,
    stylesheets=[dark_table_style],
    selectable=True,
    sortable=True,
    editable=True,     # Enable cell editing

)

# --- Show in Bokeh document ---
curdoc().add_root(column(data_table))
1 Like